c++中的多态和vptr指针

1.多态原理探究

#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;//01
//多态原理探究
//要有继承  虚函数重写  父类指针指向子类对象
class Parent
{
public:
	Parent(int a = 0)
	{
		this->a = a;
	}
	virtual void print()//动手脚 写virtual关键字,c++编译器会做特殊处理
	{
		cout << "parent" << endl;
	}
	virtual void print2()//动手脚 写virtual关键字,c++编译器会做特殊处理
	{
		cout << "parent2" << endl;
	}
private:
	int a;
};
class Child:public Parent
{
public:
	Child(int a = 0, int b = 0) :Parent(a)
	{
		this->b = b;
	}
	virtual void print()//动手脚 写virtual关键字 c++编译器会做特殊处理
	{
		cout << "Child" << endl;
	}
private:
	int b;
};

void howToPlay(Parent *base)
{
	base->print();//有多态发生,动手脚
	//效果:传来子类就执行子类的成员函数 传来父类就执行父类的成员函数
	//看起来像是c++编译器能够识别父类对象和子类对象,但是实际c++编译器不需要区分子类对象,都是vptr指针搞的鬼
	//父类对象和子类对象分别有自己的vptr指针,	=》虚函数表=》函数入口地址
	//迟绑定(函数运行时,编译器才回去判断)
}
int main()
{
	Parent	p1;//动手脚(提前布局),用类定义对象的时候,c++编译器会在对象中添加一个vptr指针
	Child	c1;//定义子类对象的时候也会添加一个vptr指针

	howToPlay(&p1);
	howToPlay(&c1);

	system("pause");
	return 0;
}

运行结果:Parent

                Child

2.证明vptr指针的存在

#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;//02
//证明vptr指针的存在
class Parent1
{
public:
	Parent1(int a = 0)
	{
		this->a = a;
	}
	void print()
	{
		cout << "Parent1(不是虚函数)" << endl;
	}
private:
	int a;
};
class Parent2
{
public:
	Parent2(int a = 0)
	{
		this->a = a;
	}
	virtual void prite()
	{
		cout << "Parent2(虚析构函数)" << endl;
	}
private:
	int a;
};
int main02()
{
	printf("sizeof(Parent1):%d	sizeof(Parent2):%d\n", sizeof(Parent1), sizeof(Parent2));
	system("pause");
	return 0;
}
//运行结果:sizeof(Parent1):4	sizeof(Parent2):8
//说明vptr的确存在,大小为4

3.vptr指针的分步初始化


#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;//03
//指针的分布初始化
//构造函数中调用虚函数能发生多态么?也就是说,初始化子类对象时候会先调用父类的构造函数,
//父类的构造函数中又有一个虚函数,此时这个虚函数是执行的子类的函数还是父类的函数
class parent
{
public:
	parent(int a = 0)
	{
		this->a = a;
		print();
	}
	virtual void print()
	{
		cout << "parent print" << 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 << "child print" << endl;
	}
private:
	int a;
	int b;
};
void playObj(parent *base)
{
	base->print();
}
int main()
{
	child c1;//定义一个子类对象 ,在这个过程中,在父类构造函数中调用虚函数print 能发生多态吗?

	system("pause");
	return 0;
}
//运行结果:parent print
//			child print
//没有发生多态
//原因:child c1;//在定义对象的时候要初始化c1.vptr指针,初始化是分步惊醒的
//当执行父类的构造函数时,c1.vptr指向父类的虚函数表,
//当父类的虚函数执行完毕时,会再把指针指向子类的虚函数表


发布了66 篇原创文章 · 获赞 19 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/RitaAndWakaka/article/details/79858204
今日推荐