C ++ - 通过引用引用调用的基本实现?

时间:2013-05-02 00:37:41

标签: c++ polymorphism mingw temporary-objects

考虑以下代码(最小版本):

#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(虚拟或非虚拟)中定义析构函数并使用临时,i时才会出现此行为。即以下用法产生'衍生':

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

2 个答案:

答案 0 :(得分:5)

Composite c((Derived()));

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

答案 1 :(得分:2)

Composite c((Derived()));

当您定义Base的析构函数并且程序离开Composite构造函数时,Derived和Base的析构函数被执行。为了避免在Base的析构函数中调用Base的虚函数时出错(现在Derived被破坏),程序将虚拟函数点(这只是该测试代码的对象的地址)从派生的指向虚函数表移动到基地。如果没有定义析构函数,则不执行任何操作。该地址仍指向Derived虚函数表。

 c.testRef();

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

我在VC 8.0中测试并检查内存。这是因为某种“幸运”。