版权声明:本文为博主原创文章,未经博主允许不得转载。 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的内容
}
}
测试结果与示意图一样: