2017-04-02 59 views
2

我有复制和移动构造这样的基类:如何使右值方法正确调用移动的构造

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

为什么你不把标签拷贝方法作为const标记到它的实例? –

+0

@LaurentG:哦,我忘了。但在这两种情况下它仍然调用复制构造函数。 – Youda008

+1

'return new Test(std :: move(* this));' – Pixelchemist

回答

3

以同样的方式,任何右值引用参数都是函数内部的左值,调用左值参考限定成员函数的对象是该成员函数内的左值。

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” 或 “指针到易失性” 等)


+0

为什么右值在函数内再次变为左值? – Youda008

+0

@ Youda008:我链接了多个相关的问题。 – Pixelchemist

+0

谢谢。公认。 – Youda008

相关问题