c++中多态的实现

在C++中,多态是一种面向对象编程的特性,允许以统一的方式处理不同类型的对象,并根据实际对象的类型来执行相应的操作。

实现原理:

多态的基本原理涉及两个概念:虚函数(virtual function)和动态绑定(dynamic binding)。

  1. 虚函数:用virtual修饰的函数,在基类中声明一个虚函数,在派生类中可以重新定义该函数。通过将函数声明为虚函数,可以实现运行时多态。示例如下:
class Base {
public:
    virtual void foo() {
        cout << "Base::foo()" << endl;
    }
//添加virtual即为虚函数,类会创建一个虚函数表,并指向该函数
};

class Derived : public Base {
public:
    void foo() override {  // 使用override关键字显式标记重写基类虚函数
        cout << "Derived::foo()" << endl;
    }
//这样调用foo()函数时,会根据实际创建的类型运行相应的代码。
};

动态绑定:当使用指向派生类对象的基类指针或引用调用虚函数时,编译器会根据指针或引用所指向的具体对象类型,在运行时动态地决定要调用哪个版本的函数。示例如下:

Base* basePtr = new Derived();  // 使用基类指针指向派生类对象
basePtr->foo();  // 动态绑定,在运行时调用Derived::foo()

上述代码会输出"Derived::foo()",即程序在运行时根据实际对象类型选择了正确的虚函数版本。

通过使用虚函数和动态绑定,可以实现多态性,即在运行时根据对象的类型来调用相应的函数版本。这为代码的灵活性、可扩展性和可维护性提供了很大的好处。

虚函数定义:

多态是由虚函数实现的,而虚函数主要是通过虚函数表实现的。如果一个类中包含虚函数,那么这个类就会包含一张虚函数表,虚函数表中存储的每一项是一个虚函数的地址。该类的每个对象都会包含一个虚指针,需指针指向虚函数表。注意:对象不包含虚函数表,只有需指针,类才包含虚函数表,派生类会生成一个兼容基类的虚函数表。

多态代码演示:

#include <iostream>  
using std::cout;  
using std::endl;  
using std::max;  
using std::min;  
  
class a {  
public: // 确保虚函数是公开的  
    virtual int num(int n1, int n2) {  
        cout << "use num in a" << endl;  
        return max(n1, n2);  
    }  
};  
  
class b : public a { // 使用冒号表示继承  
public: // 如果在类b中也要调用num函数,则num也需要是public的  
    int num(int n1, int n2) override { // override放在函数声明的末尾  
        cout << "use num in b" << endl;  
        return min(n1, n2);  
    }  
};  
  
int main() {  
    a ff1;  
    ff1.num(3, 5); // 输出:use num in a  
  
    b ff2;  
    ff2.num(3, 5); // 输出:use num in b  
  
    return 0;  
}

代码运行结果:

可以看到a类b类中都有num函数。多态使用方法为:先在基类中声明共有的虚函数,派生类继承基类,派生类重写基类中虚函数。在main函数中,虚函数就会根据实际对象的不同调用相应的代码。

多态调用与普通调用区别:

多态调用:运行时决议-- 运行时确定调用函数的地址(不管对象类型,查对应的虚函数表,如果是父类的对象,就查看父类对象中存的虚表;如果是子类切片后的对象,就查看子类切片后对象中存的虚表)
普通调用:编译时决议-- 编译时确定调用函数的地址(只看对象类型去确定调用哪个对象中的函数)

虚函数使用规则:
(1)虚函数在类中声明和类外定义的时候,virtual关键字只在声明时加上,而不能加在在类外实现上,且虚函数必须为共有函数,这是由于多态作用限制。

(2)静态成员不可以是虚函数。因为静态成员函数没有this指针,使用类型::成员函数 的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表。

(3)友元函数不属于成员函数,不能成为虚函数

(4)静态成员函数就不能设置为虚函数。

(5)析构函数建议设置成虚函数,因为有时可能利用多态方式通过基类指针调用子类析构函数(尤其是父类的析构函数强力建议设置为虚函数,这样动态释放父类指针所指的子类对象时,能够达到析构的多态)

学习链接:https://xxetb.xetslk.com/s/3nlW3Q

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值