天天看点

C++多态(动态)的实现原理

一、什么是多态

什么是多态?同一个事物多种表现形式,强调接口的重用性。看下面:

class A {
public:
	int n;
	virtual void  show() {
		cout << "A show!" << endl;
	}
    virtual void  show2() {
		cout << "A2 show!" << endl;
	}
};
class B :public A
{
public:
	void show() {
		cout << " B show!" << endl;
	}
};
class C :public A
{
public:
	void show() {
		cout << " C show!" << endl;
	}
};
int main()
{
	A *a=new A();
	B b;
	C c;
	a = &b;
	a->show();
	a = &c;
	a->show();
    return 0;
}
           

运行结果:相同的代码a->show(),结果却是不一样的!这就是多态(动态)。

C++多态(动态)的实现原理

二、实现原理

动态多态是利用虚函数实现的。在类中如果出现virtual关键字,那么这个类的大小将会多出一个指针的大小(32位4字节,64位8字节),多出来的这个指针(_vfptf)指向函数指针数组的首地址,我们称这个函数指针数组为虚函数表。

子类在继承基类时,会连同虚函数表一起继承,如果重写基类的虚函数,则会覆盖掉虚函数表中的函数地址,这就是可以调用子类对象方法的根本原因。如上:a=&b;此时基类指针指向了子类对象b的虚函数表的首地址,通过解引用就可以调用子类b中的重写的方法了。(这里解释一下,虚函数表相对于成员变量是排在前面的,所以&b的地址指向虚函数表的首地址)。

下面利用调试来看看对面的内部:

当执行完主函数第三行时,观察a,b变量(b继承a),可以看到b重写了show()函数,所以虚函数表的函数指针改变了,但是没有重写show2()函数,所以直接继承了下来,地址不变!

C++多态(动态)的实现原理

当执行完第四行a=&b时,即把b对象的地址赋给a指针,此时a指向了b对象的虚函数表,因此a就可以调用b子类对象的函数了。同理,如果a=&c,那么a指向c对象的虚函数表,a可以调用c的函数。

C++多态(动态)的实现原理

还有不明白的可以交流!(ps:其实如果画图来说应该会更直观,我偷懒截图了。。。)

上一篇: 类的多态

继续阅读