Question

Consider following code (minimal version):

#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();
}

This actually produces 'base' when using latest MinGW g++! Is that a compiler bug or am I missing something? Could someone test this in VS please?

I consider myself an experienced C++ programmer, constantly using polymorphism, stack-based references, temporary objects (C++ standard 12.2) etc. Therefore I know that lifetime lengthening should be applied.

This behaviour only occurs when defining a destructor in Base (virtual or not) and using a temporary, i. e. following usage produces 'derived':

int main()
{
    Derived d;
    Composite c(d);
    c.testRef();
}
Was it helpful?

Solution

Composite c((Derived()));

This line creates a temporary object of type Derived, passes it to the constructor of c, and then destroys the temporary object. After that, all bets are off.

OTHER TIPS

Composite c((Derived()));

When you defined destructor of Base and program leave the Composite constructor , destructor of Derived and Base executed. To avoid error when calling virtual function of Base in destructor of Base(Now the Derived is destructed ), the program move the virtual function point (which is just the address of the object of this test code) from pointing virtual function table of derived to the Base. If you do not define the destructor, then do nothing . The address is still pointing to the Derived virtual function table.

 c.testRef();

The ref still get the address of the object and the address of virtual function table, and call the function in table. So the difference exists.

I test in VC 8.0 and check the memory. This happens because some kinds of "lucky".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top