2009-03-18 5 views
3

今は私の最初の質問の時間です。代入演算子を2つのクラスの間でどのように渡しますか?代入演算子を超えていますか?

class B; 

class A { 
public: 
A &operator = (const B &b); 
friend B &B::operator = (const A &a); //compiler error 
}; 

class B { 
public: 
B &operator = (const A &a); 
friend A &A::operator = (const B &b); 
}; 

私のようなメンバ関数を宣言転送する方法を検索:

class B; 
B &B::operator = (const A &a); //error 

しかし、私は何も見つかりませんでした。私はクラスをお互いに友人にしたくないです。これはどうすればいいですか?

+0

これはどのように使用するのですか? –

+0

Bumhunter。うーん... –

+0

@ Earwicker:それは誰ですか? –

答えて

1

コンパイラエラーの原因は循環依存です。それぞれのoperator =()関数は、他のクラスのoperator =()関数に関する知識を必要とするので、クラスを定義する順序に関係なく、常にエラーが発生します。

これを並べ替える方法が1つあります。それは非常にエレガントではありませんが、それはあなたがやりたいことになります。

class A; 
class B; 

A & set_equal(A & a, const B & b); 
B & set_equal(B & a, const A & a); 

class A 
{ 
    private: 
     int x; 
    public: 
     A & operator=(const B & b) { return set_equal(*this, b); } 
     friend B & set_equal(B & b, const A & a); 
     friend A & set_equal(A & a, const B & b); 
}; 

class B 
{ 
    private: 
     int y; 
    public: 
     B & operator=(const A & a) { return set_equal(*this, a); } 
     friend A & set_equal(A & a, const B & b); 
     friend B & set_equal(B & b, const A & a); 
}; 

A & set_equal(A & a, const B & b) { a.x = b.y; return a; } 
B & set_equal(B & b, const A & a) { b.y = a.x; return b; } 

ます。また、継承してこの問題を解決できることがあります。

編集:ここでは継承を使用した例です。これは、コピー手順がAとBの両方で共有されるいくつかの共通データへのアクセスのみを必要とする場合に機能します。これは、=演算子がまったく意味を持つように思われるでしょう。

class A; 
class B; 

class common 
{ 
    protected: 
     int x; 
     void copyFrom(const common & c) { x = c.x; } 
}; 

class A : public common 
{ 
    public: 
     A & operator=(const common & c) { copyFrom(c); return *this; } 
}; 

class B : public common 
{ 
    public: 
     B & operator=(const common & c) { copyFrom(c); return *this; } 
}; 
+1

@recentのdownvoter:私のエラーは何でしたか? –

2

メンバー関数を前方宣言する方法はありません。私はあなたが欲しいものを得るためにこれよりもエレガントな方法があるかどうか分かりません(私はこのようなことをする理由は一度もありませんでした)が、2番目のクラスのメンバー以外の関数それは両方のクラスの友人で、それにコピーを委任します。その演算子に注意してください=非会員自体にはできませんが、このようなものは動作するはずです:

class B; 

class A { 
public: 
    A& operator = (const B &b); 
    friend B& do_operator_equals (B& b, const A& b); 
}; 

class B { 
public: 
    B &operator = (const A &a); 
    friend A& A::operator = (const B &b); 
    friend B& do_operator_equals (B& b, const A& a); 
}; 

そして、あなたの実装ファイルで

A& A::operator= (const B& b) { 
    // the actual code to copy a B into an A 
    return *this; 
} 

B& B::operator= (const A& a) { 
    return do_operator_equals(*this, a); 
} 

B& do_operator_equals(B& b, const A& a) { 
    // the actual code to copy an A into a B 
    return b; 
} 

編集:が後方にAさんを持って、Bさん、おっとっと。一定。

+0

これは道のりだと思いますが、私は両方の等価演算子を一貫性のために変更します。 – Jonas

-3

メンバー関数の宣言を転送しないで、クラスを宣言します。

class B; // DECLARE class B but don't define its contents 

class A { // ... uses B as above 
}; 

class B { // ... now you define the class. 
}; 

C++ FAQ section 39を参照してください。

+0

-1彼のコードを読んでいるので、彼はすでにこれをやろうとしています。問題は、両方のクラスが互いに参照し、循環依存を引き起こすことです。 –

0

なぜ、それらを最初に友人にしたいですか?
これはあなたがそれを書く方法は不可能であるようです。解決策はおそらく友人としてそれらを持っていないことであろう。

+0

友人でないなら、簡単にコピーできません。解決策は、私はそれらをまったくコピーできないということです。私は、メンバ関数やコピー工場や愚かな何かを使用することができますが、その後、それはあまりにも友人でなければならないであろう... – Jonas

関連する問題