2016-11-23 34 views
0
class B 
{ 
public: 
    B(int& a) :ref(a){} 
    B(B const&) = default; 
    int& ref; 
}; 


void main() 
{ 
    int a1 = 1, a2 = 2; 
    B b1(a1), b2(b1), b3(a2); 
    b3 = b1; 

} 

参照を生成することができない理由コンパイラの実装の暗黙的に定義されたコピー代入演算子は、暗黙的に定義されたコピー代入演算子

B& operator=(const B& rhs) 
{ 
    this->ref = rhs.ref; 
    return *this; 
} 

ある場合は?変数代入の最初のエイリアスは影響を受けません。これは、コピー代入演算子で参照変数refの数値が変更されるためです。

+3

http://stackoverflow.com/questions/26946201/why-do-reference-type-members-cause-implicitly-declared-copy-assignment-operatorのDUP? –

+2

'main'は' void'ではなく 'int'を返す必要があります。 – melpomene

答えて

1

参照は別のものにリバウンドできないため、できます。

あなたが提供するように、コンパイラが関数を生成する場合、私はこれを行うだろう:

struct Ref { 
    int& num; 
    // hypotetical operator= generated 
}; 

// ... 

int a = 2; 
int b = 5; 

Ref ra{a}; 
Ref rb{b}; 

ra = rb; // now a = 5. Quite confusing. 

a = 3; // still changes what value `ra.num` yeild. rb is not affected. 

// will print "false". 
std::cout << std::boolalpha << (ra.num == rb.num) << std::endl; 

いくつかの厄介なエラーにつながるでしょう。

私のこの問題に対する解決策は気にしないことです。ほとんどの使用例では、operator=は絶対に必要というわけではないと思います。

ただし、実際にクラスのユーザーにoperator=を提供する場合は、参照の代わりにポインタまたはstd::reference_wrapperを保持できます。どちらもあなたのクラスを割り当て可能にし、参照を再バインドすることができます。それらの2つの間で、私は通常、私の意見ではより使いやすいポインタを好む。

struct Ref { 
    std::reference_wrapper<int> num; 
}; 

// -- or -- 

struct Ref { 
    Ref(int& ref) : num{&ref} {} 

    int* num; 
}; 

// ... 

int a = 2; 
int b = 5; 

Ref ra{a}; 
Ref rb{b}; 

ra = rb; // now ra.num and rb.num are bound to the same reference. 
関連する問題