我试图了解如何有效使用智能指针,并且对它们如何与右值引用一起使用感到好奇。 std::make_shared
(也可能还有make_unique
)如何使用复制语义而不移动语义?
这是一项gtest测试,展示了我想说的话
#include <memory>
int dtor_calls = 0;
struct MoveSemanticsTest1 {
int data;
~MoveSemanticsTest1() { dtor_calls++; }
};
void reset_move_dtor_calls() {
dtor_calls = 0;
}
TEST(MoveSemanticsSanityTest1, SanityTests) {
reset_move_dtor_calls();
{
MoveSemanticsTest1 a = MoveSemanticsTest1();
}
EXPECT_EQ(1, dtor_calls); // <-- This passes, makes sense
reset_move_dtor_calls();
{
MoveSemanticsTest1 b = {3};
auto a = std::make_shared<MoveSemanticsTest1>(std::move(b));
}
EXPECT_EQ(1, dtor_calls); // <-- This fails, why?
reset_move_dtor_calls();
{
MoveSemanticsTest1 b = {3};
auto a = std::make_shared<MoveSemanticsTest1>(b);
}
EXPECT_EQ(2, dtor_calls); // <-- This passes, makes sense because of the copying
}
第二个EXPECT_EQ
失败,这表明移动的b
资源实际上并未移动资源。
答案 0 :(得分:2)
reset_move_dtor_calls();
{
MoveSemanticsTest1 b = {3}; //1
auto a = std::make_shared<MoveSemanticsTest1>(std::move(b)); //2
//3
//4
}
在1)中,您创建了一个MoveSemanticsTest1
。
在2)中,您通过移动构造来创建MoveSemanticsTest1
并将其赋予shared_ptr
。 b
处于“已移出”状态,但仍在这里。
在3)中,您破坏了shared_ptr
=>它破坏了其MoveSemanticsTest1
在4)中,您摧毁了MoveSemanticsTest1
b
。
我算了两次对析构函数的调用。