vptr指针的分步初始化导致不能在构造函数中调用虚函数发生多态


#include <iostream>
using namespace std;

//构造函数中调用虚函数能发生多态吗?

class Parent
{
public:
	Parent(int a = 0)
	{
		this->a = a;
		print();
	}

	virtual void print()
	{
		cout << "我是爹" << endl;
	}

private:
	int a;
};

class Child : public Parent
{
public:
	Child(int a = 0, int b = 0) :Parent(a)
	{
		this->b = b;
		print();
	}

	virtual void print()
	{
		cout << "我是儿子" << endl;
	}
private:
	int b;
};

void HowToPlay(Parent *base)
{
	base->print(); //有多态发生  //2 动手脚  

}

void main()
{
	//这句话要初始化vptr指针
	Child  c1; //定义一个子类对象 ,在这个过程中,在父类构造函数中调用虚函数print 能发生多态吗?
	//c1.print();

	cout << "hello..." << endl;
	system("pause");
	return;
}
/*
在vs2013中的结果是:
---------------------------------------------
我是爹
我是儿子
hello...
请按任意键继续. . .

定义一个子类对象 ,在这个过程中,在父类构造函数中调用虚函数print 能发生多态吗?
不能
为什么?
vptr指针的分步初始化问题
具体见图
当初始化父类继承过来的成员时,vptr指针指向父类虚函数列表
当初始化自己本身的成员时,指向子类的虚函数列表


Child  c1;
当执行这句话的时候,需要对对象中的vptr指针进行初始化,但是初始化是分步的
2.需要调用父类的构造函数进行初始化,当执行父类的构造函数时候,c1.vptr指向父类的虚函数表
3.如果调用虚函数就会执行父类中的虚函数。
3.当父类的构造函数运行完毕之后,会把c1.vptr指针指向子类的虚函数表
结论:子类的c2.vptr指针是分布初始化的
---------------------------------------------
*/

猜你喜欢

转载自blog.csdn.net/baixiaolong1993/article/details/89207532
今日推荐