我有基类,副本和移动构造函数如下:
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();
第一种情况正确地调用了复制构造函数,但第二种情况也错误地调用了复制构造函数。
为什么构造函数重载不能正常工作?如何让它调用移动构造函数?
答案 0 :(得分:3)
同样,任何rvalue引用参数都是函数内的左值,调用rvalue ref限定成员函数的对象是该成员函数中的左值。
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
指针,但函数的ref限定不会。 (没有&#34;指向右值&#34;或&#34;指向左值&#34的指针;但只有&#34;指向const&#34;或&#34;指向易失性&#34;等的指针。 )