C++动态多态原理分析

class Animal
{
public:
	void speak() {
		cout << "Animal.speak()" << endl;
	}
};

class Cat :public Animal 
{
	void speak() {
		cout << "Cat.speak()" << endl;
	}
};
void doWork(Animal& animal) {
	animal.speak();
}

void test01()
{
	Animal an;
	doWork(an);

	Cat cat;
	doWork(cat);
}

  doWork函数使用Animal类来接收子类执行speak(),理想状态下应该是接收什么类,就执行什么类的speak(多态),而实际情况是无论接收哪个子类的对象,都只会执行Animal.doWork(),原因是代码在编译阶段就完成了地址绑定(地址早绑定),Animal animal = cat就决定了animal.speak()是Animal类的speak而不是cat类的speak,而要实现理想效果就需要代码在运行阶段完成地址绑定(地址晚绑定)。解决办法是将父类的speak函数变为虚函数。

virtual void speak() {
	cout << "Animal.speak()" << endl;
}

在这一步后,Animal类中会多出一个名为vfptr的指针,意为虚函数表指针,其指向一个虚函数表,虚函数表内保存着虚函数的信息,借助cl工具可以查看表结构如下:

image

 而Cat类在继承Animal类后,与父类一样,同样也会有一个vfptr的指针,同样指向一个虚函数表,虚函数表内保存着父类虚函数的信息。(未对父类虚函数重写)

image

 而在子类重写父类的虚函数后,会在子类的vftable会将父类的虚函数覆盖,而父类的虚函数表不变。

image

 而此时doWork(cat)输出的就是Cat.speak()了

posted @ 2025-10-18 23:10  秋秋秋秋秋寒  阅读(5)  评论(0)    收藏  举报