C++:STL 中的智能指针

c++: smart pointer in STL

这是我的代码:

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;
}

我 运行 上面的代码在 Visual Studio 中,结果如下:

constructor
destructor
show
destructor

在我看来,show之前的constructordestructor来自Test()。我们创建了一个临时对象作为make_shared<>()的参数。所以这里我们调用构造函数和析构函数。
但是不知道为什么show后面没有constructormake_shared 不会新建一个对象吗? show 之后怎么会有 destructor 而没有 constructor 呢?或者是因为编译器做了一些我不知道的事情?

必须注意此处编译器生成的复制构造函数(或省略的副本,具体取决于编译器实现):

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

当存在用户定义的析构函数时,复制构造函数的生成是 deprecated,因此在我们的例子中,编译器要么省略复制,要么实际生成复制构造函数。

编辑

致智者之言。三法则在 C++11 及更高版本中变成了五法则(半)。我个人喜欢 Rule of all or nothing,它本质上说明如果您定义任何一个特殊成员函数(ctors、dtor、assignment),那么您应该定义所有这些函数(明确默认或删除它们,即)