如何使右值方法正确调用移动的构造
问题描述:
我有复制和移动构造这样的基类:如何使右值方法正确调用移动的构造
class Test {
public:
Test(int i) {
iptr = new int(i);
}
Test(const Test & other) {
printf("copy constructor\n");
iptr = new int(*other.iptr);
}
Test(Test && other) {
printf("move constructor\n");
iptr = other.iptr;
other.iptr = NULL;
}
virtual ~Test() {
delete iptr;
}
virtual Test * copy() {
return new Test(*this);
}
virtual Test * move() && {
return new Test(*this);
}
protected:
int * iptr;
};
我加入了复制和移动方法来允许多态复制和从一个指针移动对象,这可能会潜在地指向某个子类的一个实例。
但是当我写了下面的
Test t1(5);
Test * t2 = t1.copy();
Test * t3 = Test(6).move();
第一种情况下正确地调用拷贝构造函数,但第二种情况下错误地调用拷贝构造函数了。
为什么构造函数重载不能正常工作,我该如何调用移动构造函数?
答
以同样的方式,任何右值引用参数都是函数内部的左值,调用左值参考限定成员函数的对象是该成员函数内的左值。
void foo(Test&& x)
{
/* here x is an lvalue ! */
Test y(std::move(x)); // need explicit cast to actually move
}
因此你需要:
virtual Test * move() && {
return new Test(std::move(*this));
}
(不要忘记#include <utility>
)
之所以*this
是左值是因为间接指针总是产生一个左值,其中this
始终是一个T*
(或T cv *
)在T
类型的成员函数内。虽然成员函数cv资格影响this
指针,但函数的引用限定不会。 (没有 “指针右值” 或 “指针左值”,但只有 “指针为const” 或 “指针到易失性” 等)
为什么你不把标签拷贝方法作为const标记到它的实例? –
@LaurentG:哦,我忘了。但在这两种情况下它仍然调用复制构造函数。 – Youda008
'return new Test(std :: move(* this));' – Pixelchemist