22.多态(下)

多态原理:

虚函数表指针实际叫函数指针数组

这是虚函数表指针,这是个指针指向这张表也就是指向这个数组。

cpp 复制代码
class Person {
public:
	void BuyTicket() { cout << "买票-全价" << endl; }
protected:
	string _name;
};

class Student : public Person {
public:
	virtual void BuyTicket() { cout << "买票-打折" << endl; }

protected:
	int _id;
};

class Soldier : public Person {
public:
	virtual void BuyTicket() { cout << "买票-优先" << endl; }

protected:
	string _codename; // 代号
};

void Func(Person* ptr)
{
	// 这里可以看到虽然都是Person指针Ptr在调用BuyTicket
	// 但是跟ptr没关系,而是由ptr指向的对象决定的。
	ptr->BuyTicket();
}

int main()
{
	// 其次多态不仅仅发生在派生类对象之间,多个派生类继承基类,重写虚函数后
	// 多态也会发生在多个派生类之间。
	Person ps;
	Student st;
	Soldier sr;

	Func(&ps);
	Func(&st);
	Func(&sr);

	return 0;
}

各类的虚函数表有各自的虚函数,继承父类还有自己的成员。

怎么样能指向谁调用谁,编译器检查语法也是看满足多态吗,满足,编译这段指令时候就把这段指令变成 到指针指向这个对象的里面的虚表去找,

这个ptr无论传谁我看到的都是父类,

无论ptr指向person student codename 看到的都是person,切片以后看到的也是person,只是有可能是person,也有可能是子类切片切出来的person对象。汇编转换成指令是指针找到对象,去这个对象四个字节或者八个字节据情况而定取这个指针,通过这个指针找到函数指针的数组,这个表,在这个表里找到虚函数

父类是父类虚函数,子类是子类重写的虚函数。

person的virtual去掉就不满足多态

满足多态生成一组汇编,不满足多态生成一组汇编。不满足多态跟指向就无关,调用的都是父类

左边就是通过虚函数表指针不断找,调用

父类虚表放父类虚函数子类虚表放子类虚函数。某种程度上这也是重写的意义,执行的指令一样,但是对象的续表不一样,所以指向不同对象调用不同虚函数。

为甚不把虚函数直接放对象而放到一个表,因为很多对象可共享。同类型虚函数表是一样的,否则太冗余。

派生类的虚函数表指针是他继承的基类那一部分继承下来的,那一部分指针跟基类是不一样的。

继承类的虚函数表先把基类的虚函数表复制,然后继承类有重写的,就覆盖,没重写的就加进去,加进去的vs看不了,调用内存看,

第三个很接近,基本上确定是

拿到对象的头四个字节,就是虚函数表的地址,

强转成int* 解引用就是看头上四个字节,头上四个字节值就是指向虚表 的地址,

cpp 复制代码
int main()
{
	int i = 0;
	static int j = 1;
	int* p1 = new int;
	const char* p2 = "xxxxxxxx";
	printf("栈:%p\n", &i);
	printf("静态区:%p\n", &j);
	printf("堆:%p\n", p1);
	printf("常量区:%p\n", p2);

	Base b;
	Derive d;
	Base* p3 = &b;
	Derive* p4 = &d;
	printf("Person虚表地址:%p\n", *(int*)p3);
	printf("Student虚表地址:%p\n", *(int*)p4);
	printf("虚函数地址:%p\n", &Base::func1);
	printf("普通函数地址:%p\n", &Base::func5);
	return 0;
}

打印虚函数和普通函数就,是为了证明,他两在一个区域。只是虚函数地址又放到了虚表里面,成员函数取地址前面加&。

可以认为虚函数在VS下放到常量区

放到栈肯定不合理,函数结束,虚表销毁,两个函数,一个函数结束虚表销毁,不行。堆可以也不太合理,动态开辟没人去释放,系统自动释放倒是可以,静态区常量区更合理。取决于开发人员

相关推荐
三月微暖寻春笋8 分钟前
【和春笋一起学C++】(五十三)使用指向对象的指针
c++·初始化·指向对象的指针
菜鸟233号11 分钟前
力扣474 一和零 java实现
java·数据结构·算法·leetcode·动态规划
CoovallyAIHub15 分钟前
2026 CES 如何用“视觉”改变生活?机器的“视觉大脑”被点亮
深度学习·算法·计算机视觉
小杨同学4915 分钟前
C 语言实战:水果总价计算程序(结构体应用 + 细节优化)
后端·算法·程序员
q***441515 分钟前
Java性能优化实战技术文章大纲Java性能优化的核心目标与原则
java·开发语言·性能优化
csbysj202018 分钟前
Ruby CGI Session
开发语言
2301_8002561123 分钟前
【人工智能引论期末复习】第4章 机器学习1-基础知识
人工智能·算法·机器学习
seeksky25 分钟前
分词与 BPE 实现(tiktoken)
算法
lly20240626 分钟前
NumPy 迭代数组
开发语言
rgeshfgreh26 分钟前
Python闭包:函数记住状态的秘密
开发语言·python