首页 > 解决方案 > C++基类指针调用子虚函数,为什么基类指针可以看到子类成员

问题描述

我想我可能会混淆自己。我知道 C++ 中带有虚函数的类有一个 vtable(每个类类型一个 vtable),所以Baseclass 的 vtable 将有一个 element &Base::print(),而Childclass 的 vtable 将有一个 element &Child::print()

当我声明我的两个类对象时,base,childbasevtable_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*,但在运行时发现它将使用Childclass 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;
}

标签: c++pointerspolymorphismvirtual-functionsvtable

解决方案


通过指针的调用print执行 vtable 查找以确定要调用的实际函数。

该函数知道“this”参数的实际类型。

编译器还将插入代码以适应参数的实际类型(假设您有子类:

public base1, public base2 { void print(); };

print继承自的虚拟成员在哪里base2。在这种情况下,相关的 vtable 将不在 child 中的偏移量 0 处,因此需要进行调整以从存储的指针值转换为正确的对象位置)。

该修复所需的数据通常存储为隐藏运行时类型信息 (RTTI) 块的一部分。


推荐阅读