Search code examples
c++c++11shared-ptrsmart-pointers

Why instantiating a shared_ptr calling destructor?


Can someone explain why is the destructor of class bar being called in the line where the object of the same type is being initialized?

    #include <memory>
    #include <iostream>

    using namespace std;

    class bar
    {
      public:
        bar() {}

        ~bar() { std::cout << "destructor called " << std::endl; }
    };

    class foo
    {
      public:
        foo(std::shared_ptr<bar> barP) {}
    };


    int main() {

        std::shared_ptr<foo> f;
        std::cout << "before init " << std::endl;
        f = std::shared_ptr<foo>(new foo(std::shared_ptr<bar>(new bar())));
        std::cout << "after init"  << std::endl;
    }

Output:

before init 
destructor called 
after init

Solution

  • This statement:

    f = std::shared_ptr<foo>(new foo(std::shared_ptr<bar>(new bar())));
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    constructs a temporary shared_ptr which goes out of scope at the end of the statement. At that point, the shared_ptr goes away, taking bar with it (since no copies of the shared_ptr remain alive).

    But if you change foo to read like this:

    class foo
    {
      public:
        foo(std::shared_ptr<bar> barP) { m_bar = barP; }
        std::shared_ptr<bar> m_bar;
    };
    

    Then the output you get is probably what you were expecting, because foo maintains a copy of the shared_ptr until it (foo) goes out of scope and that copy keeps bar alive:

    before init 
    after init
    destructor called
    

    Live demo