Reputation: 10490
Why does this code compile and correctly print "Derived"
?
template <class Derived>
class Base
{
public:
Base(Derived& d) : derived(d) {}
void f() { std::cout << "Base\n"; }
virtual ~Base() { derived.f(); }
private:
Derived& derived;
};
class Derived : public Base<Derived>
{
public:
Derived() : Base<Derived>(*this) {}
void f() { std::cout << "Derived\n"; }
};
int main()
{
Derived d;
}
But either making Base::f
virtual
or both Derived::f
and Base::f
virtual causes "Base"
to be printed. Also, changing Derived::f
to virtual
gives a Invalid memory reference (SIGSEGV)
. I would expect those two other cases to print "Derived" since I'm calling it from a Derived
instance.
Why does this happen?
Upvotes: 0
Views: 97
Reputation: 126536
This is a dangling reference.
You initialize the field Base::derived
to be a reference to the Derived
object via the Derived
constructor, but then you access it in the Base
destructor after the Derived
object has been destroyed.
Access any object after it has been destroyed (via either pointer or reference) is undefined behavior, so anything might happen.
Upvotes: 2