c++ - shared_ptrs 被删除两次

标签 c++ c++11 vector shared-ptr stdvector

我想存储指向 Object 的共享指针 vector 中的类:

测试代码:

#include <vector>
#include <iostream>
#include <memory>

using namespace std;   // only for brevity

class Object
{
public:
  int n;
  Object(int n) : n(n) { cout << "Object("  << n <<")\n"; }
  ~Object() { cout << "~Object(" << n << "))\n"; n = 0xdddddddd; }

};

void Test()
{
  std::shared_ptr<Object> p1(make_shared<Object>(Object(123)));
  std::vector<shared_ptr<Object>> v;

  cout << "before push_back\n";
  v.push_back(std::make_shared<Object>(Object(2)));
  v.push_back(p1);
  cout << "after push_back\n";

  cout << "Vector content:\n";
  for (auto& p : v)
    cout << "  " << p->n << "\n"; ;
}

int main()
{
  Test();
  cout << "after Test()\n";
}

输出是
Object(123)
~Object(123))        <<< why is the destructor called here?
before push_back
Object(2)
~Object(2))          <<< why is the destructor called here?
after push_back
Vector content:
  2
  123
~Object(2))          <<< destructor called again 
~Object(123))
after Test()

我不明白为什么析构函数被调用两次。

OTOH vector 内容正是我想要的。

最佳答案

I don't understand why the destructors are called twice.



因为在这里创建了不必要的临时对象:

std::shared_ptr<Object> p1(make_shared<Object>(Object(123)));
                                               ^^^
                                               temporary object

和这里:

v.push_back(std::make_shared<Object>(Object(2)));
                                     ^^^
                                     temporary object

它应该是

std::shared_ptr<Object> p1(make_shared<Object>(123));



v.push_back(std::make_shared<Object>(2));

为什么?

因为 std::make_shared 构造一个 T 类型的对象,并使用 args 作为 T 的构造函数的参数列表将其包装在 std::shared_ptr 中。在您的代码中,您正在创建一个立即被销毁的额外对象,从而调用析构函数。

为什么不看Object(int n);构造函数被调用临时对象?
Object(int n);构造函数确实是为临时对象调用的,但是由于 std::shared_ptr 持有的对象是通过复制构造函数创建的(因此,通过复制临时对象)您不会看到对 Object(int n); 的调用为此,请调用 Object(Object const& other); .

demo ,你可以先看到Object(int n);为临时对象调用构造函数,然后调用复制构造函数 Object(Object const& other); std::shared_ptr 引用的实际对象.

关于c++ - shared_ptrs 被删除两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60322361/

相关文章:

c# - 为什么我的 2 个向量角度函数返回 NaN,即使我遵循公式

c# - XNA、矢量数学和 GPU

c++ - 数组初始值设定项必须是初始值设定项列表或字符串文字

c++ - 在 Stack 实现中使用哪个智能指针?

c++ - 短路流

C++11 等价于 boost shared_mutex

c++ - 如何将 vector<unique_ptr<T>> 复制到独立 vector<T*>

c++ - 尝试在代码块上设置 SDL

c++ - 斐波那契数列 - 动态数组

c++ - 为什么 deque 的 pop_front() 和 pop_back() 不是 noexcept?