如何强制 std::vector 使用移动构造函数而不是复制构造函数?
How to force std::vector to use move constructor instead of the copy one?
我想在我的应用程序中使用移动语义,而不是复制数据。
这是代码:
using namespace std;
struct TestData
{
TestData(const TestData&) = delete;
TestData& operator=(const TestData&) = delete;
TestData(TestData &&other) = default;
TestData& operator=(TestData &&other) = default;
TestData() { std::cout << "TestData()" << std::endl; }
~TestData() noexcept {
if(ptr != null) delete []ptr;
std::cout << "~TestData(), ptr = " << (ptr == nullptr ? "nullptr" : "not null") << std::endl;
}
int x;
char *ptr = nullptr;
};
void add(std::vector<TestData> &vector)
{
TestData d;
d.x = 1;
d.ptr = new char[12];
memcpy(d.ptr, "Test string", 11);
vector.push_back(d);
}
int main()
{
std::vector<TestData> v;
add(v);
add(v);
return 0;
}
但是 GCC 编译器失败并出现错误:
error: use of deleted function ‘TestData::TestData(const TestData&)’
但我不想复制数据,我想移动它。原因是复制数据会导致复制指针 (ptr),因此尝试在析构函数中删除它会导致双重损坏。
所以问题 - 如何强制 GCC 使用移动构造函数?
- GCC 版本 9.3.0
- Ubuntu 20.04
这次通话
vector.push_back(d);
不会调用您的移动构造函数,因为 d
不是右值引用。如果为非 r 值引用调用移动构造函数会很糟糕,因为它会撕掉本应保持完整的对象的内脏。您需要转换为 r 值引用,以明确表示您不再需要 d
。这就是 std::move
所做的(实际上只是演员):
vector.push_back(std::move(d));
但是,TestData
的默认移动构造函数没有做正确的事情。在上面的行 ptr
仍然由移动的对象拥有之后,导致双重删除。您可以通过使用 std::string
作为成员而不是 char *
.
来防止出现这种情况以及您的字符串未被空终止的问题
我想在我的应用程序中使用移动语义,而不是复制数据。 这是代码:
using namespace std;
struct TestData
{
TestData(const TestData&) = delete;
TestData& operator=(const TestData&) = delete;
TestData(TestData &&other) = default;
TestData& operator=(TestData &&other) = default;
TestData() { std::cout << "TestData()" << std::endl; }
~TestData() noexcept {
if(ptr != null) delete []ptr;
std::cout << "~TestData(), ptr = " << (ptr == nullptr ? "nullptr" : "not null") << std::endl;
}
int x;
char *ptr = nullptr;
};
void add(std::vector<TestData> &vector)
{
TestData d;
d.x = 1;
d.ptr = new char[12];
memcpy(d.ptr, "Test string", 11);
vector.push_back(d);
}
int main()
{
std::vector<TestData> v;
add(v);
add(v);
return 0;
}
但是 GCC 编译器失败并出现错误:
error: use of deleted function ‘TestData::TestData(const TestData&)’
但我不想复制数据,我想移动它。原因是复制数据会导致复制指针 (ptr),因此尝试在析构函数中删除它会导致双重损坏。
所以问题 - 如何强制 GCC 使用移动构造函数?
- GCC 版本 9.3.0
- Ubuntu 20.04
这次通话
vector.push_back(d);
不会调用您的移动构造函数,因为 d
不是右值引用。如果为非 r 值引用调用移动构造函数会很糟糕,因为它会撕掉本应保持完整的对象的内脏。您需要转换为 r 值引用,以明确表示您不再需要 d
。这就是 std::move
所做的(实际上只是演员):
vector.push_back(std::move(d));
但是,TestData
的默认移动构造函数没有做正确的事情。在上面的行 ptr
仍然由移动的对象拥有之后,导致双重删除。您可以通过使用 std::string
作为成员而不是 char *
.