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/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
36 2
C++入门12——详解多态1
|
1月前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
79 1
|
1月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
39 1
|
1月前
|
程序员 C++ 开发者
C++入门教程:掌握函数重载、引用与内联函数的概念
通过上述介绍和实例,我们可以看到,函数重载提供了多态性;引用提高了函数调用的效率和便捷性;内联函数则在保证代码清晰的同时,提高了程序的运行效率。掌握这些概念,对于初学者来说是非常重要的,它们是提升C++编程技能的基石。
21 0
|
3月前
|
存储 编译器 C++
|
3月前
|
存储 编译器 C++
C++多态实现的原理:深入探索与实战应用
【8月更文挑战第21天】在C++的浩瀚宇宙中,多态性(Polymorphism)无疑是一颗璀璨的星辰,它赋予了程序高度的灵活性和可扩展性。多态允许我们通过基类指针或引用来调用派生类的成员函数,而具体调用哪个函数则取决于指针或引用所指向的对象的实际类型。本文将深入探讨C++多态实现的原理,并结合工作学习中的实际案例,分享其技术干货。
71 0
|
4月前
|
机器学习/深度学习 PyTorch 算法框架/工具
C++多态崩溃问题之在PyTorch中,如何定义一个简单的线性回归模型
C++多态崩溃问题之在PyTorch中,如何定义一个简单的线性回归模型
下一篇
无影云桌面