-1

Why was destructor of Derived class called in this code?

#include <iostream>

class Base
{
public:
   Base() { std::cout << "Base::Base() \n"; }
   ~Base() { std::cout << "Base::~Base() \n"; } 
};

class Derived : public Base
{
public:
   Derived() { std::cout << "Derived::Derived() \n"; }
   ~Derived() { std::cout << "Derived::~Derived() \n"; } 
};

Derived foo() { return Derived(); }

int main()
{
   const Derived& instance = foo();
}
FrozenHeart
  • 19,844
  • 33
  • 126
  • 242
  • 10
    Why wouldn't it be? – eq- Sep 05 '12 at 17:20
  • Because a `Derived` object was destroyed. The implication in your question is that you think the destructor wouldn't be called. Why is this? – CB Bailey Sep 05 '12 at 17:21
  • What did you expect? You can not return a local object because it will be destroyed as soon as it goes out of scope. – Alex Sep 05 '12 at 17:23
  • It looks like the entire `Base` class is nothing but a red herring. It has nothing to do with the question at all?! – Kerrek SB Sep 05 '12 at 17:23
  • There isn't virtual keyword for destructor in Base class – FrozenHeart Sep 05 '12 at 17:25
  • 3
    @NikitaTrophimov: Why do you think that is relevant? You never `delete` a `Derived` object through a pointer to `Base`. – CB Bailey Sep 05 '12 at 17:26
  • It's UB only when using new and delete for classes which hasn't virtual destructor? – FrozenHeart Sep 05 '12 at 17:45
  • See here for virtual destructor information: http://stackoverflow.com/questions/11681790/parent-class-has-a-virtual-function-is-it-necessary-to-have-a-virtual-destructo/ – CB Bailey Sep 05 '12 at 18:21

2 Answers2

3

Why was destructor of Derived class called in this code?

Because the Derived instance created in foo() is going out of scope at the end of main program.

#include <iostream>
using namespace std;

class Base {
public:
    Base() {
        std::cout << "Base::Base() \n";
    }
    ~Base() {
        std::cout << "Base::~Base() \n";
    }
};

class Derived: public Base {
public:
    int i;
    Derived() {
        i = 10;
        std::cout << "Derived::Derived() \n";
    }
    ~Derived() {
        i = 0;
        std::cout << "Derived::~Derived() \n";
    }
    int get() {
        return i;
    }
};

Derived foo() {
    return Derived();
}

int main() {
    const Derived& instance = foo();
    cout << instance.i << endl;
    return 0;
}

The output is as follows:

Base::Base()
Derived::Derived()
10
Derived::~Derived()
Base::~Base()
Vikdor
  • 23,934
  • 10
  • 61
  • 84
  • 4
    `instance` isn't an object. It's a reference. References going out of scope don't usually cause destructors to be called. I think you need to expand your explanation. – CB Bailey Sep 05 '12 at 17:23
  • @CharlesBailey, I spoke too soon without checking it's a reference and thought OP got confused with virtual function behavior. Corrected my explanation. Thanks for correcting! – Vikdor Sep 05 '12 at 17:33
  • In this case, the reference is initialized with a temporary (whose lifetime is extended to match that of the reference), so although `instance` isn't an object, it has an object associated with it. – James Kanze Sep 05 '12 at 17:35
3

To make it more interesting, consider a modified main:

const Base& instance = foo();

That code creates a temporary (the object returned by foo) of type Derived and extends the lifetime of the object by binding it to a constant reference of type Base. The lifetime of the temporary will be extended until the reference goes out of scope at which point the object will get destroyed. The code is roughly translated to:

Derived __tmp = foo();
const Base& instance = __tmp;

At the end of the block holding the reference instance, the __tmp variable also goes out of scope and gets deleted. Note that even with no virtual destructor, the appropriate destructor is called, as __tmp is of type Derived (the type returned by the function).

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489