1
class Base {
public:
    Base() {
        std::cout << "Base::ctor" << std::endl;
    }
    ~Base() {
        std::cout << "Base::dtor" << std::endl;
    }
};

class Derived : public Base {
    public:
    Derived() {
        std::cout << "Derived::ctor" << std::endl;
    }
    ~Derived() {
        std::cout << "Derived::dtor" << std::endl;
    }
};

int main(int argc, char** argv){
    std::unique_ptr<Base> b = std::make_unique<Derived>();
}

The correct output is:

Base::ctor
Derived::ctor
Base::dtor

But according to me, it should be:

Base::ctor
Derived::ctor
Derived::dtor
Base::dtor

Can someone explain why this order of output ?? Why does it not follow the intended order ?

arshellium
  • 215
  • 1
  • 6
  • 17
  • 5
    Make `~Base()` virtual – Edgar Rokjān Apr 19 '18 at 19:19
  • 2
    You have UB in your code, make destructor virtual – Slava Apr 19 '18 at 19:20
  • I know that Boost's `shared_pointer` did that, at the cost of an additional allocation for the pointer management structure. I think that this feature was carried over into the C++ 11 standard. – Ulrich Eckhardt Apr 19 '18 at 19:21
  • You need to declare the base class destructor as virtual to let the compiler know it should look up the destructor in the vtable of the derived class. – arynaq Apr 19 '18 at 19:22
  • This code would have produced the same output if using raw pointers with `new` and `delete`, fyi. [Here is what your code should look like](https://wandbox.org/permlink/S41B8EncTR3BSojH) – Ryan Haining Apr 19 '18 at 19:24
  • @UlrichEckhardt that's correct. A crucial part of what makes that easy to adopt is that the Deleter isn't part of the `shared_ptr`'s type, whereas it is a template argument to the `unique_ptr` – Ryan Haining Apr 19 '18 at 19:26
  • I guess what confuses me are the unique_ptr and make_unique constructs. Any source to understand these better? – arshellium Apr 19 '18 at 19:51

0 Answers0