Search code examples
c++11shared-ptr

c++: smart pointer in STL


Here is my code:

class Test
{
public:
    Test(){ cout << "constructor" << endl; }
    ~Test(){ cout << "destructor" << endl; }
    void show(){ cout << "show" << endl; }
};

int main()
{
    vector<shared_ptr<Test>> vec;
    vec.push_back(make_shared<Test>(Test()));
    vec[0]->show();
    vec.clear();
    return 0;
}

I run the code above in Visual Studio and here is the result:

constructor
destructor
show
destructor

In my opinion, constructor and destructor before show come from Test(). We created a temporary object as the parameter of make_shared<>(). So here we call the constructor and destructor.
But I don't know why there isn't any constructor after show. Won't make_shared new an object? How could we have a destructor without any constructor after show? Or it's because the compiler did something that I don't know?


Solution

  • Gotta be aware of compiler-generated copy constructors here (or elided copies depending on compiler implementation):

    class Test
    {
    public:
        Test(){ cout << "constructor" << endl; }
        ~Test(){ cout << "destructor" << endl; }
        Test(const Test& other){cout << "copy" << std::endl;}
        void show(){ cout << "show" << endl; }
    };
    
    int main()
    {
        vector<shared_ptr<Test>> vec;
        vec.push_back(make_shared<Test>(Test()));
        vec[0]->show();
        vec.clear();
        return 0;
    }
    

    constructor
    copy
    destructor
    show
    destructor

    Demo

    The generation of a copy constructor when there is a user defined destructor is deprecated, so in our case the compiler is either eliding the copy, or actually generating a copy constructor.

    Edit

    A word to the wise. The Rule of Three has become the Rule of Five (and a half) in C++11 and beyond. I personally like the Rule of all or nothing which essentially states that if you define any one of the special member functions (ctors, dtor, assignment), then you should define ALL of them (explicitly default or delete them, that is)