c++ - C++基类指针调用子虚函数,为什么基类指针可以看到子类成员
问题描述
我想我可能会混淆自己。我知道 C++ 中带有虚函数的类有一个 vtable(每个类类型一个 vtable),所以Base
class 的 vtable 将有一个 element &Base::print()
,而Child
class 的 vtable 将有一个 element &Child::print()
。
当我声明我的两个类对象时,base
,child
的base
vtable_ptr 将指向Base
类的 vtable,而child
' 的 vtable_ptr 将指向Child
类的 vtable。在我将 base 和 child 的地址分配给 Base 类型指针的数组之后。我打电话给base_array[0]->print()
和base_array[1]->print()
。我的问题是,在运行时,两者都base_array[0]
属于base_array[1]
type Base*
,尽管 v-table 查找会给出正确的函数指针,但Base*
类型如何能看到类中的元素Child
?(基本上值2?)。当我打电话时base_array[1]->print()
,base_array[1]
是 type Base*
,但在运行时发现它将使用Child
class print()
。但是,我很困惑为什么value2
在这段时间可以访问,因为我正在玩类型Base*
......我想我一定错过了什么地方。
#include "iostream"
#include <string>
using namespace std;
class Base {
public:
int value;
string name;
Base(int _value, string _name) : value(_value),name(_name) {
}
virtual void print() {
cout << "name is " << name << " value is " << value << endl;
}
};
class Child : public Base{
public:
int value2;
Child(int _value, string _name, int _value2): Base(_value,_name), value2(_value2) {
}
virtual void print() {
cout << "name is " << name << " value is " << value << " value2 is " << value2 << endl;
}
};
int main()
{
Base base = Base(10,"base");
Child child = Child(11,"child",22);
Base* base_array[2];
base_array[0] = &base;
base_array[1] = &child;
base_array[0]->print();
base_array[1]->print();
return 0;
}
解决方案
通过指针的调用print
执行 vtable 查找以确定要调用的实际函数。
该函数知道“this”参数的实际类型。
编译器还将插入代码以适应参数的实际类型(假设您有子类:
public base1, public base2 { void print(); };
print
继承自的虚拟成员在哪里base2
。在这种情况下,相关的 vtable 将不在 child 中的偏移量 0 处,因此需要进行调整以从存储的指针值转换为正确的对象位置)。
该修复所需的数据通常存储为隐藏运行时类型信息 (RTTI) 块的一部分。
推荐阅读
- php - 输入文本框时不显示自动完成,但控制台中显示值
- c++ - 如何对继承的文件使用前向声明
- amazon-s3 - logstash 输出 s3 文件名
- database - 使用laravel导入时如何防止在数据库中复制csv文件?
- html - 我想在影响导航栏的图片上悬停
- php - 如何从 symfony 表单的多维字段中勾选特定复选框?
- python - 如何将具有相同文件名的csv导入数据框,应用一些程序,然后合并?
- azure - Azure 表:ExcuteBatch 返回什么结果?
- powershell - 从文本文件中获取最大数字并将其作为 var 递增 1
- r - 如何删除远程(postgresql)表上的排序?