为什么boost :: make_shared使用复制语义

时间:2016-06-16 21:03:07

标签: c++ boost

我有一个小程序,我的工作我无法理解。

class A {
     public:
     A() {
        cout<<"Costructor called"<<endl;
    }

    ~A() {
        cout<<"Destructor called"<<endl;
    }
};

A foo() {
    return A();
}


int main() {
    A obj = foo();
    cout<<"A initialized "<<endl;
    boost::shared_ptr<A> ptr1 = boost::make_shared<A>(foo());
    cout<<"ptr1 initialized "<<endl;
return 0;
}

输出是: -

./a.out
Costructor called
A initialized 
Costructor called
Destructor called
ptr1 initialized 
Destructor called
Destructor called

为什么在创建ptr时初始化和销毁​​,但在创建obj时却没有?

4 个答案:

答案 0 :(得分:1)

boost::make_shared<A>(foo())相当于boost::shared_ptr<A>(new A(foo()))new A(foo())将调用默认的复制构造函数(如果你正在使用C ++ 11,则调用默认的移动构造函数)。

从更高阶的角度来看,foo()的返回值是在堆栈上的临时存储中创建的,而shared_ptr需要堆分配的对象才能释放内存当引用计数变为0时。

答案 1 :(得分:1)

通过添加复制构造函数并在每个特殊成员中打印this,让我们的课程有点吵闹

class A {
     public:
     A() {
        cout<<"Constructor called "<< this << endl;
    }

    A(A const&) {
        cout<<"Copy Constructor called "<< this << endl;
    }

    ~A() {
        cout<<"Destructor called "<< this << endl;
    }
};

Live demo

这会产生输出

Constructor called 0x7fff0ed4883e   // obj is constructed
A initialized 
Constructor called 0x7fff0ed4883f   // return value of foo() is constructed in make_shared call
Copy Constructor called 0x1430c39   // shared_ptr copy constructs A from return value of foo()
Destructor called 0x7fff0ed4883f    // return value of foo() is destroyed
ptr1 initialized 
Destructor called 0x1430c39         // shared_ptr deletes the A it owns
Destructor called 0x7fff0ed4883e    // obj is destroyed

答案 2 :(得分:0)

我想在第一种情况下编译器使用RVO优化,因此在foo函数内部构造了obj。

答案 3 :(得分:0)

A initializedptr1 initialized之间调用的构造函数/析构函数对

./a.out
Costructor called
A initialized 
Costructor called // <- !
Destructor called // <- !
ptr1 initialized 
Destructor called
Destructor called

用于函数A

foo()类型的临时实例
A foo() {
    return A(); // you are creating the instance (constructor call)
}

因为这是一个临时对象:

  

所有临时对象都被销毁,作为评估的最后一步   表达式(词法上)包含它们所在的点   创建

http://en.cppreference.com/w/cpp/language/lifetime

这意味着析构函数调用就在构造函数调用之后。

此行为与boost::shared_ptrboost::make_shared()无任何关联或特定。尝试替换

boost::shared_ptr<A> ptr1 = boost::make_shared<A>(foo());

A ptr1 = foo();

并检查差异。