首页 > 编程语言 >多态性 - C++中实现运行时多态的方式

多态性 - C++中实现运行时多态的方式

时间:2023-08-22 14:14:12浏览次数:43  
标签:函数 多态性 float 多态 C++ Shape calculateArea public

一、概述

C++中的多态性是指同一个函数可以有多种不同的实现方式,并且在运行时根据实际情况进行选择执行。在C++中实现多态有两种方式:静态多态和动态多态。静态多态是指在编译时确定函数的实现,包括函数重载和模板函数;动态多态是指在运行时根据对象的实际类型来确定函数的实现,包括虚函数和抽象类。

二、静态多态

1、函数重载

函数重载是指在同一个作用域中定义多个同名函数,它们的参数列表不同。编译器会根据函数的参数列表唯一地确定要调用的函数。函数重载的实现可以通过编译时的函数匹配来实现,实现起来比较简单。 下面是一个函数重载的示例代码:

#include <iostream>

void print(int i) {
    std::cout << "This is an integer: " << i << std::endl;
}

void print(float f) {
    std::cout << "This is a float: " << f << std::endl;
}

int main() {
    print(42);
    print(3.14f);
    return 0;
}

上面的代码中,我们定义了两个同名的函数`print`,但是它们的参数列表不同,一个接受整数,一个接受浮点数。在调用函数`print`时,编译器会自动根据参数的类型选择调用哪个函数。

2、模板函数

模板函数是指在定义函数时使用了类型参数,可以让函数适用于多种不同的类型。编译器会在编译时根据参数类型来生成具体的函数实现。模板函数的实现可以通过编译时的模板实例化来实现。 下面是一个模板函数的示例代码:

#include <iostream>
#include <cstdlib>

template <typename T>
T max(T a, T b) {
    return a > b ? a : b;
}

int main() {
    int x = 42, y = 23;
    float f = 3.14f, g = 2.71f;
    std::cout << "Max of " << x << " and " << y << " is " << max(x, y) << std::endl;
    std::cout << "Max of " << f << " and " << g << " is " << max(f, g) << std::endl;
    return 0;
}

上面的代码中,我们定义了一个模板函数`max`,它可以针对整数、浮点数等多种类型进行运算。在调用函数`max`时,编译器会根据参数类型自动推断出要使用哪个具体的函数实现。

三、动态多态

1、虚函数

虚函数是指在基类中定义的函数可以被派生类重写的函数。通过将函数声明为虚函数,我们可以在运行时根据对象的实际类型来确定要调用的函数实现。在C++中,只要将函数声明为虚函数即可实现动态多态。 下面是一个虚函数的示例代码:

#include <iostream>

class Shape {
public:
    virtual float calculateArea() { return 0; }
};

class Square : public Shape {
public:
    Square(float l) : _length(l) {}
    virtual float calculateArea() { return _length * _length; }
private:
    float _length;
};

class Circle : public Shape {
public:
    Circle(float r) : _radius(r) {}
    virtual float calculateArea() { return 3.14f * _radius * _radius; }
private:
    float _radius;
};

int main() {
    Shape *s1 = new Square(5);
    Shape *s2 = new Circle(3);
    std::cout << "Area of square is " << s1->calculateArea() << std::endl;
    std::cout << "Area of circle is " << s2->calculateArea() << std::endl;
    delete s1;
    delete s2;
    return 0;
}

上面的代码中,我们定义了一个基类`Shape`和两个派生类`Square`和`Circle`,它们都实现了函数`calculateArea`。在调用函数`calculateArea`时,我们将基类指针指向派生类对象,可以看到运行时实际调用的是派生类的实现函数。

2、抽象类

抽象类是指包含至少一个纯虚函数的类,这个类不能被实例化,只能用作基类来派生出其他类。在C++中,可以通过将函数声明为纯虚函数来实现抽象类。 下面是一个抽象类的示例代码:

#include <iostream>

class Shape {
public:
    virtual float calculateArea() = 0;
};

class Square : public Shape {
public:
    Square(float l) : _length(l) {}
    virtual float calculateArea() { return _length * _length; }
private:
    float _length;
};

class Circle : public Shape {
public:
    Circle(float r) : _radius(r) {}
    virtual float calculateArea() { return 3.14f * _radius * _radius; }
private:
    float _radius;
};

int main() {
    // Shape *s = new Shape();  // error: cannot instantiate abstract class
    Shape *s1 = new Square(5);
    Shape *s2 = new Circle(3);
    std::cout << "Area of square is " << s1->calculateArea() << std::endl;
    std::cout << "Area of circle is " << s2->calculateArea() << std::endl;
    delete s1;
    delete s2;
    return 0;
}

上面的代码中,我们将基类`Shape`中的函数`calculateArea`声明为纯虚函数,从而实现了抽象类。抽象类不能被实例化,只能用作基类来派生出其他类。在调用函数`calculateArea`时,我们将基类指针指向派生类对象,可以看到运行时实际调用的是派生类的实现函数。

四、总结

本文介绍了C++中实现运行时多态的两种方式:静态多态和动态多态。静态多态包括函数重载和模板函数,动态多态包括虚函数和抽象类。通过对这些知识点的学习,可以更好地理解C++中的多态性,更灵活地应用在实际的程序开发中。

标签:函数,多态性,float,多态,C++,Shape,calculateArea,public
From: https://www.cnblogs.com/10zhan/p/17648342.html

相关文章

  • paddleocr在华为升腾920上编译C++ cpu版的推理
    最好用这个提供的docker环境华为昇腾NPU-PaddlePaddle深度学习平台编译推理库飞腾/鲲鹏下从源码编译—Paddle-Inferencedocumentation(paddlepaddle.org.cn)编译成功后还需要报错 Noruletomaketarget'/root/workspace/Paddle/build/paddle_inference_install_dir......
  • 4.8 C++ Boost 应用JSON解析库
    property_tree是Boost库中的一个头文件库,用于处理和解析基于XML、Json或者INFO格式的数据。property_tree可以提供一个轻量级的、灵活的、基于二叉数的通用容器,可以处理包括简单值(如int、float)和复杂数据结构(如结构体和嵌套容器)在内的各种数据类型。它可以解析数据文件到......
  • 4.9 C++ Boost 命令行解析库
    命令行解析库是一种用于简化处理命令行参数的工具,它可以帮助开发者更方便地解析命令行参数并提供适当的帮助信息。C++语言中,常用的命令行解析库有许多,通过本文的学习,读者可以了解不同的命令行解析库和它们在C++项目中的应用,从而更加灵活和高效地处理命令行参数。一般比较常见的解......
  • 4.8 C++ Boost 应用JSON解析库
    property_tree是Boost库中的一个头文件库,用于处理和解析基于XML、Json或者INFO格式的数据。property_tree可以提供一个轻量级的、灵活的、基于二叉数的通用容器,可以处理包括简单值(如int、float)和复杂数据结构(如结构体和嵌套容器)在内的各种数据类型。它可以解析数据文件......
  • 4.9 C++ Boost 命令行解析库
    命令行解析库是一种用于简化处理命令行参数的工具,它可以帮助开发者更方便地解析命令行参数并提供适当的帮助信息。C++语言中,常用的命令行解析库有许多,通过本文的学习,读者可以了解不同的命令行解析库和它们在C++项目中的应用,从而更加灵活和高效地处理命令行参数。一般比较常见的解......
  • C++简介
    一、C++介绍本贾尼.斯特劳斯特卢普,于1979年在贝尔实验室负责分析UNIX系统内核流量的分布情况时,特别希望有一种更加模块化的工具,于1979.10开始着手研发一款新的编程语言,在C语言的基础上增加了面向对象的机制,也就是C++,1983年完成了C++的第一个版本C++与C的关联和重要区别:(面试题)......
  • 标准C++ -- day01
    一、C++介绍本贾尼.斯特劳斯特卢普,于1979年在贝尔实验室负责分析UNIX系统内核流量的分布情况时,特别希望有一种更加模块化的工具,于1979.10开始着手研发一款新的编程语言,在C语言的基础上增加了面向对象的机制,也就是C++,1983年完成了C++的第一个版本C++与C的关联和重要区别:(面试题)......
  • C++的对象与类的含义
    C++是一门面向对象的编程语言,理解C++需要掌握类(class)和对象(object)这两个概念。C++中的类(Class)可以看做C语言中结构体(Struct)的升级版。结构体是一种构造类型,可以包含若干成员变量,每个成员变量的类型可以不同;可以通过结构体来定义结构体变量,每个变量拥有相同的性质。例如:#include<s......
  • C++遍历TypeList(可变模板参数)的简单办法
        这里例举了两种方案,一种是基于C++17的constexpr,实现起来更精简。另外一种使用传统的方式,C++11就可以用了。    另外C++11的方案也是一种计算不定参数模板参数个数的方法。#include<iostream>#include<string>//inC++17#if((defined(_MSVC_LANG)......
  • C++ 字符串类 string
    @TOC前言在C++中,字符串是一种常见的数据类型,用于存储和操作文本数据。C++标准库中提供了std::string类,它是一个功能强大的字符串类,提供了丰富的方法和操作符,使我们能够轻松地处理字符串。一、string类型概括std::string是C++标准库中定义的字符串类,它在<string>头文件中声明。它......