【发布时间】:2021-03-08 20:13:40
【问题描述】:
我正在学习如何创建移动构造函数,所以我创建了一个名为 Test 的类,它有一个,就像教程中的那些:
class Test {
private:
int* arr;
int size;
public:
Test() {
arr = new int[100];
size = 100;
for (int i = 0; i < 100; i++) {
arr[i] = i;
}
}
Test(Test&& other) {
arr = other.arr;
size = other.size;
other.arr = nullptr;
other.size = 0;
}
};
出于好奇,我删除了右值引用以查看它是否适用于“旧引用”:
class Test {
private:
int* arr;
int size;
public:
Test() {
arr = new int[100];
size = 100;
for (int i = 0; i < 100; i++) {
arr[i] = i;
}
}
Test(Test& other) {
arr = other.arr;
size = other.size;
other.arr = nullptr;
other.size = 0;
}
};
令我惊讶的是,它运行良好。所以我的问题是: 如果我们之前能够构建完美的移动构造函数,为什么他们将其添加到语言中?
【问题讨论】:
-
std::auto_ptr会是一本有趣的书,关于我们之前能够做到的事情。 -
“它工作得很好” 您是否尝试将不使用右值引用的临时值传递给您的版本? Lets see how well this code works.
-
不要把它仅仅看作是一个“移动”构造函数,也要把它看作一个rvalue reference构造函数。第二个变体不能处理第一个可以的所有情况,或者一个适当的复制构造函数。事实上,当用作复制构造函数时,其行为会非常令人惊讶。
-
简短回答 - 因为它会在不应该编译的地方编译,而在应该编译的地方失败。
-
Test(Test& other)不是move constructor,它是一个copy constructor,它不正确地实现了移动语义而不是复制语义。
标签: c++ move-semantics