我有这个代码
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()
{
}
Run Code Online (Sandbox Code Playgroud)
在打击时,我得到了结果:
Setup start
TC Construct 0
TC Deconstruct 0
TC Deconstruct 0
Run Code Online (Sandbox Code Playgroud)
我预计,当shared_ptr超出范围时,TC上的解构函数只会被调用一次.
谁知道第二次通话的原因?
谁知道第二次通话的原因?
因为构造了两个对象.使用std::make_shared<TC>(TC());,首先TC构造临时TC(),然后复制它以构造由管理的第二个对象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;
};
Run Code Online (Sandbox Code Playgroud)
顺便说一句:对于这种情况,临时是不必要的,你可能只想要std::make_shared<TC>();.