Search code examples
c++virtual-functionstemporarypure-virtual

c++ temporary - "pure virtual method called"


As I understand temporaries, the following code should work, but it doesn't.

struct base
{
    virtual~base() {}
    virtual void virt()const=0;
};
struct derived:public base
{
    virtual void virt()const {}
};

const base& foo() {return derived();}

int main()
{
    foo().virt();
    return 0;
}

The call to virt() gives a "pure virtual function called" error. Why is that, and what should I do?


Solution

  • It seems like you're expecting the const reference to extend the lifetime of the temporary. There are certain situations where this doesn't occur. One of those situations is when returning a temporary:

    The second context [in which temporaries are destroyed at a different point than the end of the full-expression] is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

    [...]

    • The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.

    Since calling a member function of the object returned by foo() will necessitate an lvalue-to-rvalue conversion and the object is invalid (not derived from type base), you get undefined behaviour:

    If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.