views:

75

answers:

2

If you have a templated base class as in the following example:

class A{
   public:
    A();
    virtual ~A();
};

template <class T>
class B : public T
{
  public:
    B();
    virtual ~B();
};

typedef B<A> C;

class D : public C
{
  public:
    D();
    virtual ~D();
};

When you delete an instance of D, will the destructor of A be called?

I'll probably create a test program to find out what happens, but just thinking about it, I wasn't sure what should happen.

+3  A: 

When you delete an instance of D, will the destructor of A be called?

Yes. Nothing special here (except you have private access on everything, which means it probably won't compile).

jpalecek
Just an oversight on the public access. Added an edit to correct the example.I think you're right, but it's hard for me to envision how that works.
Mutmansky
D inherits from C which inherits from A, so D's destructor call's A's destructor. What's the bit that's hard to envision?
You're right. I think it's just late and templates make my head hurt. It's really no different then if you take the template part out of the equation and simply had three layers of inheritance.
Mutmansky
+2  A: 

In a bid to get rep from two contradictory answers, given:

#include <iostream>
using namespace std;

class A{
    public:
    A() {}
    virtual ~A() { cout << "~A()\n"; }
};

template <class T>
class B : public T
{
    public:
    B() {}
    virtual ~B() {}
};

typedef B<A> C;

class D : public C
{
    public:
    D() {}
    virtual ~D() {}
};

int main() {
    D d;
}

Then yes, of course A's destructor will be called.

anon
Yeah, as noted in a comment below, this is actually nothing mysterious. For whatever reason, the template aspect made me scratch my head for a minute, but it really shouldn't.
Mutmansky
One interesting thing. I actually implemented basically the same test as you did above, but the cout in the destructor of A was printed out twice in my example. Hhhmmm... There must be some other aspect of the real code (that I didn't capture in this simplified example) that I'm missing.
Mutmansky
@Mutmansky Should definitely only print once, for the above. BTW, when posting simplified examples like this, use structs rather than classes - then you won't have problems with public/private.
anon
Turns out the constructor of D was creating a local object of the base type and using the copy to to initialize the it's own base C. i.e. it was calling the copy constructor of C (aka B<A>). So, the constructor of D looked like:D( ): C( A() ){}That accounts for the extra call to A's destructor. Sinister...
Mutmansky