创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
c语言内容💖:
专栏:c语言之路重点知识整合
【c语言】全部知识点总结
目录
- 一、多态的概念
- 二、虚函数
- 1.虚函数大小
- 2.虚函数指针
- 3.虚函数列表
一、多态的概念
多态是C++面向对象编程中重要的特性。相同的行为方式可能导致不同的行为结果,即产生了多种形态行为,即多态。
就是不同的类可以共享一个函数,但是各自的实现不同
为了实现多态,首先要有继承关系,在基类中声明一个虚函数
,然后再派生类中进行不同的实现
根据继承中的父类指针可以指向子类对象:继承的条件下,父类的指针可以指向任何继承于该类的子类对象,多种子类对象具有多种形态由父类的指针统一管理 父类的指针也会具有多种形态
多种子类表现为多种形态由父类的指针进行统一,那么这个父类指针就具有了多种形态。(多态)
总结一下C++多态的必要条件:
- 存在继承关系,并且父类类型的指针指向某个子类,通过该指针调用虚函数
- 父类中存在虚函数 (virtual修饰) ,且子类中重写了父类的虚函数
重写:虚函数存在的前提下,子类中定义了和父类中一模一样的虚函数
举个栗子:
定义两个子类CSon
和CSon2
继承于父类CFather
,父类中定义两个虚函数
只在CSon
子类中进行重写,在CSon2
中不重写
#include <iostream>
using namespace std;
class CFather {
public:
virtual void funSon()
{
cout << "CFather::virtual void fun()" << endl;
}
virtual void funSon2()
{
cout << "CFather::virtual void fun()" << endl;
}
};
class CSon :public CFather
{
public:
void fun1()
{
cout << "CSon::fun1()" << endl;
}
void funSon()
{
cout << "CSon::virtual void fun()" << endl;
}
};
class CSon2 :public CFather
{
public:
void funSon2()
{
cout << "CSon2::virtual void fun()" << endl;
}
};
int main()
{
CFather* pfa = new CSon;
pfa->funSon(); //非多态
pfa->funSon2(); //多态
return 0;
}
其中:重写过父类中虚函数的CSon
类中的funSon()
实现多态,而未重写的funSon2()
未实现多态
什么是虚函数?虚函数是如何实现多态的?
二、虚函数
1.虚函数大小
定义虚函数需要使用virtual
关键字,虚函数的定义格式: virtual 返回类型 函数名();
virtual void fun();
当只定义一个空类时,输出类对象的大小为1
:为占位作用
如果在类中定义虚函数后,对象的内存空间会变为多少呢?
定义后执行发现,不管定义几个虚函数,对象的内存空间大小都为4
即
虚函数属于类,在编译器存在
2.虚函数指针
当我们在基类中定义了一个虚函数后并定义对象后(不定义对象没有虚函数指针),在调试下可以发现编译期自动添加了一个类型为void**
的二级指针_vfptr
再定义一个对象,虚函数指针也随之增加了一个
但是查看地址,这两个虚函数指针指向了同一个内存空间,
即
虚函数指针属于对象,占用对象内存空间,定义多个对象就会存在多份的虚函数指针
-
定义对象才会存在虚函数指针
-
每个对象的虚函数指针都指向了同一个虚函数列表
-
虚函数指针在构造函数中的初始化参数列表进行初始化(编译期自动完成)
3.虚函数列表
虚函数指针指向的是一个函数指针数组,为虚函数列表(vftable)
其中
每一个元素存储的是虚函数的地址,顺序为虚函数在类中定义顺序
- 虚函数列表属于类,在编译期存在,为所有对象共享
- 必须通过真实存在的对象调用,无对象或空指针对象无法调用虚函数
大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。 |
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●) |