C++多态的基本概念与原理刨析

简介: 多态分为两类• 静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名• 动态多态: 派生类和虚函数实现运行时多态静态多态和动态多态区别:• 静态多态的函数地址早绑定 - 编译阶段确定函数地址• 动态多态的函数地址晚绑定 - 运行阶段确定函数地址下面通过案例进行讲解多态



多态的基本概念

多态是C++面向对象三大特性之一

多态分为两类

  • 静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名
  • 动态多态: 派生类和虚函数实现运行时多态

静态多态和动态多态区别:

  • 静态多态的函数地址早绑定  -  编译阶段确定函数地址
  • 动态多态的函数地址晚绑定  -  运行阶段确定函数地址

下面通过案例进行讲解多态

classAnimal

{

public:

   voidspeak()

   {

       cout<<"动物在说话"<<endl;

   }

};

classCat :publicAnimal

{

public:

   voidspeak()

   {

       cout<<"小猫在说话"<<endl;

   }

};

voidDoSpeak(Animal&animal)

{

   animal.speak();

}

voidtest01()

{

   Catcat;

   DoSpeak(cat);//想让猫说话,但是输出结果是动物说话

}

intmain() {

   test01();

   system("pause");

   return0;

}

案例分析:

想让猫说话,但是输出结果是动物说话,原因是因为执行说话的函数speak()地址早绑定了,在编译阶段就已经确定了函数地址。

如果想执行猫说话,那么这个函数地址就不能提前绑定,需要在运行阶段绑定。

解决方案:

classAnimal

{

public:

   //Speak函数就是虚函数

   //函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了。

   virtualvoidspeak()

   {

       cout<<"动物在说话"<<endl;

   }

};

classCat :publicAnimal

{

public:

   

   voidspeak()

   {

       cout<<"小猫在说话"<<endl;

   }

};

voidDoSpeak(Animal&animal)

{

   animal.speak();

}

voidtest01()

{

   Catcat;

   DoSpeak(cat);//使用了虚函数后,输出结果:小猫在说话

}

intmain() {

   test01();

   system("pause");

   return0;

}

相当于speak()现在有多种形态了,根据传入的对象不同确定不同的函数地址。

总结:

多态满足条件

  • 有继承关系
  • 子类重写父类中的虚函数,子类可写可不写

多态使用条件

  • 父类指针引用指向子类对象

PS:

  • 重写:函数返回值类型  函数名 参数列表 完全一致称为重写
多态的原理刨析

classAnimal

{

public:

   //Speak函数就是虚函数

   //函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了。

   virtualvoidspeak()

   {

       cout<<"动物在说话"<<endl;

   }

};

classCat :publicAnimal

{

public:

   voidspeak()

   {

       cout<<"小猫在说话"<<endl;

   }

};

//我们希望传入什么对象,那么就调用什么对象的函数

//如果函数地址在编译阶段就能确定,那么静态联编

//如果函数地址在运行阶段才能确定,就是动态联编

voidDoSpeak(Animal&animal)

{

   animal.speak();

}

//多态满足条件:

//1、有继承关系

//2、子类重写父类中的虚函数

//多态使用:

//父类指针或引用指向子类对象

voidtest01()

{

   Catcat;

   DoSpeak(cat);

}

voidtest02()

{

   cout<<sizeof(Animal) <<endl;

}

intmain() {

   test02();

   system("pause");

   return0;

}

案例分析:

在Animal中的speak()函数为加上关键字virtual时是一个非静态成员函数,不属于类的对象上,该类类似于一个空类,占一个字节,

加上关键字后运行发现这个类占4个字节(PS:不管什么指针都占4个字节,可以考虑指针),多了一个vfptr(virtual function pointer虚函数(表)指针),指向vftable(虚函数表)

子类的替换继承过来的父类的speak()


目录
相关文章
|
1月前
|
存储 编译器 C++
【C++】深度解剖多态(下)
【C++】深度解剖多态(下)
37 1
【C++】深度解剖多态(下)
|
1月前
|
存储 编译器 C++
|
26天前
|
机器学习/深度学习 算法 C++
C++多态崩溃问题之为什么在计算梯度下降时需要除以批次大小(batch size)
C++多态崩溃问题之为什么在计算梯度下降时需要除以批次大小(batch size)
|
26天前
|
JSON Go C++
开发与运维C++问题之在iLogtail新架构中在C++主程序中新增插件的概念如何解决
开发与运维C++问题之在iLogtail新架构中在C++主程序中新增插件的概念如何解决
29 1
|
1月前
|
Java 编译器 C++
【C++】深度解剖多态(上)
【C++】深度解剖多态(上)
35 2
|
1月前
|
C++ 开发者
C++一分钟之-概念(concepts):C++20的类型约束
【7月更文挑战第4天】C++20引入了Concepts,提升模板编程的类型约束和可读性。概念定义了模板参数需遵循的规则。常见问题包括过度约束、约束不完整和重载决议复杂性。避免问题的关键在于适度约束、全面覆盖约束条件和理解重载决议。示例展示了如何用Concepts限制模板函数接受的类型。概念将增强模板的安全性和灵活性,但需谨慎使用以防止错误。随着C++的发展,Concepts将成为必备工具。
54 2
|
26天前
|
机器学习/深度学习 PyTorch 算法框架/工具
C++多态崩溃问题之在PyTorch中,如何定义一个简单的线性回归模型
C++多态崩溃问题之在PyTorch中,如何定义一个简单的线性回归模型
|
1月前
|
程序员 C++
【C++】揭开C++多态的神秘面纱
【C++】揭开C++多态的神秘面纱
|
1月前
|
C++ 开发者
C++一分钟之-概念(concepts):C++20的类型约束
【7月更文挑战第6天】C++20引入了Concepts,提升模板编程的精确性和可读性。概念允许设定模板参数的编译时约束。常见问题包括过度约束、不完整约束及重载决议复杂性。要避免这些问题,需适度约束、全面覆盖约束条件并理解重载决议。示例展示了如何定义和使用`Incrementable`概念约束函数模板。概念是C++模板编程的强大力量,但也需谨慎使用以优化效率和代码质量。
50 0
|
1月前
|
编译器 程序员 C++
【C++高阶】掌握C++多态:探索代码的动态之美
【C++高阶】掌握C++多态:探索代码的动态之美
27 0