一分钟教你真正搞明白C++多态

有那么多讲C++多态的文章,但是却没有一个能真正看明白的,神秘的多态机制,究竟是如何实现的,看黄老师来如何教你?

我们先看两个类:


class A

{

public:

A() { a = 111; }

virtual void  fun1()

{

cout << " A::fun1" << endl;

}

virtual void fun2()

{

cout << " A::fun2" << endl;

}

int a;

};

class  B:public A

{

public:

B() { b = 222; }

virtual void  fun2()

{

cout << " B::fun2" << endl;

}

virtual void fun3()

{

cout << " B::fun3" << endl;

}

int b;

};


简单介绍下规则:

1. 首先对于含有virtual关键字的类(A  或  B), 该类的所有对象的内存的前四个字节(32位系统下),存放一个内存地址,根据这个地址可以访问到该类的虚函数表内存(表中的每一项都是一个函数地址 ,所以A中有两项  fun1  ,fun2 )。

2. 派生类(自己有virtual 或者 基类中有 virtual 关键字),  根据1规则,同样有一张虚函数表内存 ( 表中的每一项都是一个函数地址,按道理来说应该是四项   A类中的 fun1  ,fun2 , B类中的fun2, fun3 ,这个时候需要注意,派生类的fun2 会覆盖基类的fun2, 所以只有三项) 

用图解释如下:


作为一个最喜欢扒内存的黄老师而言,利用代码测试其内存结构,便能一清二楚!!!

#include <iostream> 

using namespace std;

typedef  void(*PFUN)();

class  A

{

public:

A() { a = 111; }

virtual void  fun1()

{

cout << " A::fun1" << endl;

}

virtual void fun2()

{

cout << " A::fun2" << endl;

}

int a;

};

class  B:public A

{

public:

B() { b = 222; }

virtual void  fun2()

{

cout << " B::fun2" << endl;

}

virtual void fun3()

{

cout << " B::fun3" << endl;

}

int b;

};

int main()

{

//根据多态我们知道,肯定调用的是B的fun2

//A  *p = new B;

//p->fun2();

cout << "---------------------------A的虚函数表--------------------------" << endl;

{

cout << "A类的大小 " << sizeof(A) << endl;

//测试A的虚函数表

A    a;

int *pA = (int *)&a;//a内存空间的首地址

cout << "4字节vtable指针"<<endl;

int * vptr = (int *)(*pA); // a内存空间的 前4个字节 存放的内容是  虚函数表的地址

PFUN  afun1 = (PFUN)vptr[0];

afun1();

PFUN  afun2 = (PFUN)vptr[1];

afun2();

cout <<"4字节a成员"<< *(pA + 1)<<endl;  //成员变量a的内容

}

cout << "---------------------------B的虚函数表--------------------------" << endl; 

{

cout << "B类的大小 " << sizeof(B) << endl;

//测试B的虚函数表

B    b;

int *pB = (int *)&b;//b内存空间的首地址

cout << "4字节vtable指针" << endl;  //成员变量a的内容

int * vptr = (int *)(*pB); // b内存空间的 前4个字节 存放的内容是  虚函数表的地址

PFUN  bfun1 = (PFUN)vptr[0];

bfun1();

PFUN  bfun2 = (PFUN)vptr[1];

bfun2();

PFUN  bfun3 = (PFUN)vptr[2];

bfun3();

cout << "4字节a成员" << *(pB + 1) << endl;  //成员变量a的内容

cout << "4字节b成员" << *(pB + 2) << endl;  //成员变量b的内容

}

}

测试结果与示意图一样:

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容