首页 > 解决方案 > C++ shared_ptr 调用拥有对象的解构器

问题描述

我有这个代码

class TC
{
public:
   TC()
   {
        i_idx = s_idx++;
        Serial.printf("TC Construct %d\r\n", i_idx);
  };

  virtual ~TC()
  {
        Serial.printf("TC Deconstruct %d\r\n",i_idx);
  };

  int i_idx;
  static int s_idx;
};

int TC::s_idx = 0;

void setup()
{
    Serial.begin(115200);
    Serial.printf("\r\n\nSetup start\r\n");
    std::shared_ptr<TC> stc = std::make_shared<TC>(TC());
}

void loop()
{
}

执行时我得到结果:

Setup start
TC Construct 0
TC Deconstruct 0
TC Deconstruct 0

我希望当 shared_ptr 超出范围时,TC 上的解构器只会被调用一次。

有人知道第二次打电话的原因吗?

标签: c++shared-ptr

解决方案


有人知道第二次打电话的原因吗?

因为构造了两个对象。使用,首先构造std::make_shared<TC>(TC());一个临时对象,然后将其复制以构造由 . 管理的第二个对象。TCTC()std::shared_ptr

您可以添加复制/移动构造函数以获得更清晰的观察;你会看到两次建设和两次破坏。例如

class TC
{
public:
  TC()
  {
        i_idx = s_idx++;
        Serial.printf("TC Construct %d\r\n", i_idx);
  }

  TC(const TC&)
  {
        i_idx = s_idx++;
        Serial.printf("TC copy Construct %d\r\n", i_idx);
  }

  TC(TC&&)
  {
        i_idx = s_idx++;
        Serial.printf("TC move Construct %d\r\n", i_idx);
  }

  virtual ~TC()
  {
        Serial.printf("TC Deconstruct %d\r\n",i_idx);
  }

  int i_idx;
  static int s_idx;
};

顺便说一句:对于这种情况,临时是不必要的,你可能只想要std::make_shared<TC>();.


推荐阅读