2017-04-02 61 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

相關問題