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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HQ354974212/article/details/86642594

有那么多讲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的类, 该类的所有对象都有一个指针域, 指向同一张虚函数表,表中是虚函数的地址

2. 派生类的所有对象都有一个指针域, 指向另外一张虚函数表,这张函数表中是基类与派生类的虚函数地址,如果重名,则覆盖

用图解释如下:

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

#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的内容

	}

}

测试结果与示意图一样:

猜你喜欢

转载自blog.csdn.net/HQ354974212/article/details/86642594