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()


目录
相关文章
|
2月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
2月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
2月前
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
28天前
|
存储 编译器 数据安全/隐私保护
【C++】多态
多态是面向对象编程中的重要特性,允许通过基类引用调用派生类的具体方法,实现代码的灵活性和扩展性。其核心机制包括虚函数、动态绑定及继承。通过声明虚函数并让派生类重写这些函数,可以在运行时决定具体调用哪个版本的方法。此外,多态还涉及虚函数表(vtable)的使用,其中存储了虚函数的指针,确保调用正确的实现。为了防止资源泄露,基类的析构函数应声明为虚函数。多态的底层实现涉及对象内部的虚函数表指针,指向特定于类的虚函数表,支持动态方法解析。
32 1
|
2月前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
47 2
C++入门12——详解多态1
|
2月前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
88 1
|
2月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
46 1
|
2月前
|
程序员 C++ 开发者
C++入门教程:掌握函数重载、引用与内联函数的概念
通过上述介绍和实例,我们可以看到,函数重载提供了多态性;引用提高了函数调用的效率和便捷性;内联函数则在保证代码清晰的同时,提高了程序的运行效率。掌握这些概念,对于初学者来说是非常重要的,它们是提升C++编程技能的基石。
26 0
|
4月前
|
存储 编译器 C++
|
5月前
|
机器学习/深度学习 算法 C++
C++多态崩溃问题之为什么在计算梯度下降时需要除以批次大小(batch size)
C++多态崩溃问题之为什么在计算梯度下降时需要除以批次大小(batch size)