通过引用派生的来调用C++基实现

C++ - base implementation called through reference of derived?

本文关键字:调用 C++ 实现 引用 派生      更新时间:2023-10-16

考虑以下代码(最低版本(:

#include <iostream>
struct Base
{
    virtual ~Base() {}
    virtual void test() const { std::cout << "base"; }
};
struct Derived : public Base
{
    void test() const { std::cout << "derived"; }
};
struct Composite
{
    const Derived &ref;
    Composite(const Derived &ref) : ref(ref) {}
    void testRef() const { ref.test(); }
};
int main()
{
    Composite c((Derived()));
    c.testRef();
}

当使用最新的MinGW g++时,这实际上产生了"基础"!这是编译器错误还是我遗漏了什么?有人能在VS中测试一下吗?

我认为自己是一名经验丰富的C++程序员,经常使用多态性、基于堆栈的引用、临时对象(C++标准12.2(等。因此,我知道应该应用寿命延长。

只有当在Base(虚拟或非虚拟(中定义析构函数并使用临时函数时,才会发生这种行为,例如,以下用法产生"派生":

int main()
{
    Derived d;
    Composite c(d);
    c.testRef();
}
Composite c((Derived()));

此行创建一个类型为Derived的临时对象,将其传递给c的构造函数,然后销毁该临时对象。之后,所有赌注都取消了。

Composite c((Derived()));

当您定义了Base和程序的析构函数时,将执行Composite构造函数、Derived和Base的析构因子。为了避免在Base的析构函数中调用Base的虚拟函数时出错(现在Derived被析构函数了(,程序将虚拟函数点(它只是这个测试代码的对象的地址(从Derived的虚拟函数表移到Base。如果没有定义析构函数,那么什么也不做。该地址仍指向派生虚拟函数表。

 c.testRef();

ref仍然获取对象的地址和虚拟函数表的地址,并调用表中的函数。所以差异是存在的。

我在VC 8.0中测试并检查内存。发生这种情况是因为某种"幸运"。