2011-12-09 8 views
0

クラスに参照変数がある場合は、オーバーロードされた代入演算子を記述する必要があります。あなたはこの問題を解決するにはどうすればよい代入演算子のオーバーロードを扱う。あなたは参照を再割り当てできますか?

MyClass& MyClass::operator=(const MyClass& rhs) 
{ 
    if (&rhs != this) 
    { 
     myReference = rhs.myReference; 
    } 
    return *this; 
} 

:私はあなただけのような何かを行うことができないので、インスタンス上の参照を一度設定してできた印象の下に

でしたか?

EDIT - OKですので、参照のあるクラスで代入演算子を使用することはできません。しかし、なぜビジュアルスタジオは私にそれをさせるのですか?プログラムは実行され、すべてが実行されます。

+2

サイドノート:コピースワップイディオムを使用すると、 '&rhs!= this'チェックは冗長です(http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-イディオム)。 –

+0

@SirYakalot:私の編集をご覧ください。私はこれがあなたのために物事を明確にすることを望む。 –

答えて

1

いいえ、あなたは参照を再座席することはできません。

は考えてみましょう:

int a = 42, b = 43; 
int &ar = a; 
ar = b; 

はどのようにコンパイラを使用すると、bを参照するためにarを取り付け直ししようとしていることを知っている、と43aを設定することはできませんか?

この「問題」は、参照ではなくポインタを使用して解決します。

EDIT:あなたの編集パー、

OKはので、私はあなたが罰金、 参照してクラスの代入演算子を使用することはできません聞いています。しかし、なぜビジュアルスタジオは私にそれをさせるのですか? プログラムが実行されます。

あなたの結論の前提は間違っています。 は、参照を含むクラスで代入演算子を使用します。あなたがすることができないことは、参照を再座らせることです。上のコードで説明したように、ar = a;を使用して参照を再割り当てしようとすると、arが何を参照するのかはわかりませんが、arの値を変更します。

Visual Studioで「することができます」ということは難しくありません。誤解は、Visual Studioがあなたに任せていることです。それはあなたが参照を再座らせることを許可していません。それはあなたが参照の価値を変更させるものです。これが意味するものを明確にすることを望む例がここにあります。

#include <iostream> 
#include <string> 
using namespace std; 

class Foo 
{ 
public: 
    void dump() const 
    { 
     cout << "Foo instance " << showbase << this << "\n"; 
    } 
}; 

class Bar 
{ 
public: 
    Bar(Foo& foo) : foo_(foo) {} 
    Bar& operator=(const Bar& rhs) 
    { 
     foo_ = rhs.foo_; 
     return * this; 
    } 

    void dump() const 
    { 
     cout << showbase << "Bar instance " << this << "\t"; 
     foo_.dump(); 
    } 

private: 
    Foo& foo_; 
}; 

int main() 
{ 
    cout << "foo1: "; 
    Foo foo1; 
    foo1.dump(); 

    cout << "foo2: "; 
    Foo foo2; 
    foo2.dump(); 

    cout << "bar1 :"; 
    Bar bar1(foo1); 
    bar1.dump(); 

    cout << "bar2 :"; 
    Bar bar2(foo2); 
    bar2.dump(); 

    bar2 = bar1; 
    cout << "bar2 after assign :"; 
    bar2.dump(); 
} 

上記のコードは2つのFooオブジェクト(foo1foo2)を確立し、異なるFooへの参照をそれぞれ有する2つのBarオブジェクトを作成します。 Barは、次のことを実行する、operator=があります

foo_ = rhs.foo_; 

C++はfoo_が今Fooの別のインスタンスを参照することになり、あなたがこの方法で再座席の参照をすることができます。しかし、それはしません。これはfoo_が何を参照するかを変更しません。代わりにFoooperator=が呼び出されます。上記のコードを実行すると、Fooのアドレスがbar2に変更されないことがわかります。参照を再配置できる場合は、参照が変更されます。

+0

@Downvoter:downvoteの理由は? –

+0

を使用すると、参照を含むクラスに対してオーバーロードされた代入演算子を記述することができます。どのような初期化リストの参照のための適切な構文ですか? – SirYakalot

+0

@SirYakalot:単純に 'obj :: obj():ref_(ref){};' –

0

あなたは、参照を使用するクラスと代入演算子を作ることができますが、この行:

myReference = rhs.myReference; 

は、参照を再割り当てしません。参照が参照していることを再割り当てする場合。したがって、その割り当ての後、myReferenceとrhs.myReferenceは同じオブジェクトを参照しません。しかし、彼らが今参照しているものは同等の値を持っています。

再割り当て可能な参照が必要な場合は、ポインタを使用します。それが彼らのためのものです。実際には、現代のC++では、これがローポインタのために残っている唯一の使用法です。参照しているオブジェクトが動的に割り当てられている場合は、shared_ptrに入れ、myReferenceを別のshared_ptrまたはweak_ptrにする必要があります。

+0

あなたが生のポインタについて話し始めたので、アップヴォートを取り去ってください。彼はポインタを使うべきであり、スマートなポインタでなければならない可能性があります。 –

+0

@BenVoigt:あなたが指しているものが既にスマートポインタに含まれていて、あなたのコントロール下にない場合は、スマートポインタしか使用できません。スマートポインタは動的に割り当てられたオブジェクト用であり、時には動的に割り当てられていないものへの参照が必要な場合があります。 –

+0

真ですが、生のポインターが間違いなくここに適切であることを意味するわけではありません。 –

0

2つの言葉で - あなたはできません。参照には実際のオブジェクトのセマンティクスがあるため、代入演算子は実際には参照オブジェクトではなく、基本オブジェクトの代入を呼び出します。

+0

リファレンスを持つクラスの代入演算子を書く方法はありませんか? – SirYakalot

+0

@SirYakalot:いいえ、自分の投稿を参照してください。 –

+0

@SirYakalot:私にはないと思われます。 –

0

参照はリバウンドできません。

しかし、コードはあなたが思う通りに行動していなくても合法です。リファレンスを再バインドまたは再割り当てするのではなく、参照先(参照のターゲット)に割り当てます。

+0

それは大丈夫ですか?元のオブジェクトをそれ自体に設定しているだけなので、これは問題ありません。それともコピーがまだそれ自体の参照なしであることを意味するのでしょうか? – SirYakalot

+0

どのような動作が必要かによって異なります。多くの場合、指示対象を割り当てることは正しい動作です。 2つのオブジェクトは依然として異なるメモリ位置を参照しますが、メモリ位置の値は一方から他方へコピーされています。 –

0

あなたのコードは書かれているように動作しますが、ではなく、が参照を再割り当てします。

myReference = rhs.myReference; 

rhs.myReferenceによって参照されるオブジェクトをmyReferenceに割り当てます。したがって、代入&myReference != &(rhs.myReference)が真であった前に、代入の後でもそれは真ですが、それらのアドレスのオブジェクトには同じ値が含まれています(myReference == rhs.myReferenceの場合はoperator==が定義されています)。参照を再割り当てする(不可能)とは、割り当てが&myReference == &(rhs.myReference)の後にtrueになることを意味します。実際の質問は、あなたがしたいことです:で参照されるオブジェクトをthis->myReference(その場合コードは問題ありません)によって参照されるオブジェクトにコピーしたいのですか、this->myReferenceと同じオブジェクトを参照するようにしますか? rhs.myReference(これは参照では不可能なので、ポインタを使う必要があります)。

関連する問題