2017-12-22 15 views
3
class TestClass 
{ 
    public: 
    TestClass(){ 
     cout<<"constructor"<<endl; 
     p = {1,2,3}; 
     cout<<(unsigned int *)(this->p.data())<<endl; 
    } 
    TestClass(const TestClass& test): p(std::move(test.p)) 
    { 
     cout <<"copy constructor"<<endl; 
     cout<<(unsigned int *)(this->p.data())<<endl; 

    } 
    TestClass(TestClass && test): p(std::move(test.p)) 
    { 
     cout <<"move constructor"<<endl; 
     cout<<(unsigned int *)(this->p.data())<<endl; 
    } 
    private: 
     std::vector<int> p; 
}; 


int main() 
{ 
    TestClass t{}; 
    TestClass p{t}; 
    TestClass s{std::move(p)}; 
    return 0; 
} 

と出力コンストラクタ下記のアドレスはコピーコンストラクタ以下のものとは異なる、なぜ私は疑問に思ってカスタムクラスのコピーコンストラクタでこのベクターを移動できないのはなぜですか?

constructor 
0xb92bf0 
copy constructor 
0xb915b0 
move constructor 
0xb915b0 

です。私が理解しているものでも、それはコピーコンストラクタですが、私はstd :: moveを使ってrvalue参照を取得し、ベクトルの移動コンストラクタを呼び出す必要があります。

+4

移動するには、ソースオブジェクトを変更する必要があります。 – StoryTeller

+6

コピーコンストラクタは、移動しないコピー用です。それは、コンストラクタを移動するためのものです。このようなセマンティクスを変更すると、そのクラスのコピーコンストラクターがどのように動作するかについてのborkの期待が得られます。 –

+2

'TestClass(const TestClass&test)' 'const'は' move'を 'move'しないと思います。もし' const'を削除すれば、あなたは何を期待しているのでしょうか?なぜ 'copy ctor''が' move'ですか? – PYA

答えて

4

std::moveはxvalueに渡されたものをキャストするだけなので、rvalue-referencesはそれにバインドしてリソースを盗む可能性があります。ここで:

TestClass(const TestClass& test): p(std::move(test.p)) 

std::moveは、あなたが見ることができるように、const修飾子を持つ、タイプconst std::vector<int> &&、の表現を生成します。あなたが著作をチェックし[vector]std::vectorの-コンストラクタを移動する場合は、移動、コンストラクタはタイプstd::vector<T> &&の発現を期待して、コピーコンストラクタはconst std::vector<T> &を期待していることがわかります:

vector(const vector& x); 
vector(vector&&) noexcept; 

は、結果を比較しますstd::move(test.p)をこれら2つのコンストラクタに追加します。 rvalue-referenceはconst修飾子付きの型にバインドしないため(rvalue-referenceがconst -qualifiedの場合を除く)、移動コンストラクタのオーバーロードは適切ではありません。他の候補(コピーコンストラクタ)は、const -qualifiedタイプを受け入れず、xvaluesは右辺値と同じ特性を有するので:

http://en.cppreference.com/w/cpp/language/value_category#rvalue

右辺値はで、CONST左辺値の参照を初期化するために使用されてもよい

この場合、rvalueによって識別されるオブジェクトの有効期間は、参照の範囲が終了するまで延長されます。

は、コピーコンストラクタが適切な候補であり、選択されています。

関連する問題