35 多态原理

当类中声明虚函数时,编译器会在类中生成一个虚函数表

虚函数表是一个存储类成员函数指针的数据结构

#include<iostream>
using namespace std;

// 多态成立三条件
// 继承 虚函数重写 父类指针指向子类
class Parent {
public:
	Parent(int a = 0) {
		this->a = a;
	}

	virtual void print() {	// virtual 放入虚函数表
		cout << "Parent" << endl;
	}
private:
	int a;
};

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

	virtual void print() {
		cout << "Child" << endl;
	}
private:
	int b;
};

void play(Parent* base) {
	base->print();	// 多态 传父类执行父类成员函数;传子类执行子类成员函数
	// 父类对象和子类对象分别有vptr指针,找虚函数表,再找函数的入口
}

void main() {
	Parent p1;	//用类定义对象 c++编译器会在对象中添加vptr指针
				// 提前布局
	
	Child c1;	// vptr指针

	play(&p1);
	play(&c1);
}

加virtual多4个字节,证明vptr指针的存在?

// 证明vptr指针
class Parent1 {
public:
	Parent1(int a = 0) {
		this->a = a;
	}

	void print() {	// virtual 放入虚函数表
		cout << "Parent" << endl;
	}
private:
	int a;
}; 

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

	virtual void print() {	// virtual 放入虚函数表
		cout << "Parent" << endl;
	}
private:
	int a;
};

void main() {
	cout << "sizeof(Parent1):" << sizeof(Parent1) << endl;
	cout << "sizeof(Parent2):" << sizeof(Parent2) << endl;
}

结果

sizeof(Parent1):4
sizeof(Parent2):8

1 构造函数中调用虚函数能实现多态吗?

在这里插入图片描述

// 构造函数中调用虚函数能多态吗
class Parent {
public:
	Parent(int a = 0) {
		this->a = a;
		print();
	}

	virtual void print() {	// virtual 放入虚函数表
		cout << "Parent" << 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" << endl;
	}
private:
	int b;
};


void main() {

	Child c1;	// 创建子类对象,父类过程中print虚函数能发生多态吗?(不会)

}

案例:父类指针和子类指针的步长

父类指针和子类指针++步长不是一个概念

在这里插入图片描述

// 父类指针和子类指针的步长
class Parent {
public:
	Parent(int a = 0) {
		this->a = a;
	}

	virtual void print() {	// virtual 放入虚函数表
		cout << "Parent" << endl;
	}
private:
	int a;
};

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

	virtual void print() {
		cout << "Child" << endl;
	}
private:
	int b;
};


void main() {
	Child c1;

	Parent* pP = NULL;
	Child* pC = NULL;


	Child array[] = { Child(1),Child(2), Child(3) };
	pP = array;
	pC = array;

	pP->print();	// 此时 pP地址为0x0093f760
	pC->print();	// 	   pC	  0x0093f760

	pP++;			// 0x0093f768	4个字节(int a)+virtual
	pC++;			// 0x0093f76C	8(int a)(int b) + virtual 

	//pP->print(); 这是会报错
	pC->print();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值