move构造函数的实现方式通常是这样的:
class Test {
public:
int *ptr;
Test() {
}
Test(Test&& t) {
ptr = t.ptr;
t.ptr = nullptr;
}
};
int main() {
Test t = Test(Test());
return 0;
}
为什么我们不能像这样实现它们:
class Test {
public:
int *ptr;
Test() {
}
Test(Test& t) {
ptr = t.ptr;
t.ptr = nullptr;
}
};
int main() {
Test t = Test(Test());
return 0;
}
第二段代码似乎运行得很好。我不明白为什么我们不能那样做。
2条答案
按热度按时间0g0grzrc1#
你当然能做到。你的代码的用户(包括你未来的自己)会诅咒你。
对于一个接受右值的移动构造函数,你必须说你想把它放大:
mutmk8jj2#
不能将非
const
左值引用绑定到右值(也就是说,不能使用prvalues和xvalues),所以特殊的构造函数不能用于临时或移动操作。在您的例子中,它之所以编译,是因为您使用的是C++17或更高版本,其中
Test t = Test(Test());
等价于Test t;
,因为强制复制/移动省略1)。您的特殊构造函数根本没有使用。只有默认构造函数为。1)
t
由相同类型的prvalue初始化,因此= T(...)
直接初始化t
。参见Copy elision on cppreference