如何使rvalue方法正确调用move构造函数

时间:2017-04-02 10:58:55

标签: c++ constructor move-semantics

我有基类,副本和移动构造函数如下:

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();

第一种情况正确地调用了复制构造函数,但第二种情况也错误地调用了复制构造函数。

为什么构造函数重载不能正常工作?如何让它调用移动构造函数?

1 个答案:

答案 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;等的指针。 )