gpt4 book ai didi

C++基类指针调用子虚函数,为什么基类指针能看到子类成员

转载 作者:行者123 更新时间:2023-11-28 01:33:26 26 4
gpt4 key购买 nike

我想我可能把自己弄糊涂了。我知道 C++ 中具有虚函数的类有一个 vtable(每个类类型一个 vtable),所以 Base 类的 vtable 将有一个元素 &Base::print(),而 Child 类的 vtable 将有一个元素 &Child::print()

当我声明我的两个类对象时,basechildbase 的 vtable_ptr 将指向 Base 类的虚表,而 child 的 vtable_ptr 将指向 Child 类的虚表。在我将 base 和 child 的地址分配给一个 Base 类型指针数组之后。我调用了 base_array[0]->print()base_array[1]->print()。我的问题是,base_array[0]base_array[1] 在运行时都是 Base* 类型,尽管 v-表查找将给出正确的函数指针,Base* 类型如何看到 Child 类中的元素? (基本上值 2?)。当我调用 base_array[1]->print() 时,base_array[1]Base* 类型,但在运行时它发现out 它将使用 Childprint()。但是,我很困惑为什么这段时间可以访问value2,因为我正在玩type 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) block 的一部分。

关于C++基类指针调用子虚函数,为什么基类指针能看到子类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50539965/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com