【发布时间】:2019-12-11 19:47:45
【问题描述】:
我试图了解我应该如何有效地使用智能指针,我很好奇它们如何与右值引用一起工作。为什么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 资源实际上并未移动资源。
【问题讨论】:
-
std::move 只是对右值引用进行强制转换,什么也不移动。目标变量将保持有效状态,因此将调用析构函数
-
您的移动构造函数/移动赋值运算符在哪里?请注意,
std::move只是 强制转换 到右值引用。它不会自己做任何事情。
标签: c++ smart-pointers move-semantics