2011-07-15 61 views
1

我通讀了很多循環依賴主題,但他們都似乎關心聲明。我很感興趣如何構建相互依賴的對象,以及我的方法是否存在潛在的缺陷。考慮一個簡單的例子:C++循環依賴:構造函數應該是什麼樣子?

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

class A; //Forward declaration 

class B{ 
    public: 
     B(string name, A* a):myA(a), name(name){ 
      cout << "Works with pointer" << endl; 
     }; 
    private: 
     A* myA; 
     string name; 

}; 

class A{ 
    public: 
     A(){ 
      cout << "Constructing A" << endl; 
      if(bs.empty()) cout << "Vector is empty" << endl; 
      bs.push_back(B("First", this)); 
      cout << "Array has " << bs.size() << " elements." << endl; 
     }; 
    private: 
     std::vector<B> bs; 
}; 


int main() { 
    cout << "Start" << endl; 
    A a; 
    cout << "Ok." << endl; 
    return 0; 
} 

有什麼事情我可以做,以避免BA*指針?

理想情況下,我想有一個參考,但如果我改變的B構造函數B(string name, A& a),然後的push_back改變bs.bush_back(B("First", *this));我得到一個錯誤:non-static reference member 'A& B::myA', can't use default assignment operatorSee the modified example

據我所知operator=由編譯器合成不適合在這裏。 operator=將如何看起來像?還是我一起走錯了方向?

+0

如果您有圓形依賴關係,那麼你應該刪除它,而不是尋找更多的解決方法。 –

+0

嗯,我的(語言不可知的)域模型具有循環依賴性。有什麼方法可以解決課堂設計水平上的問題嗎? – sebastiangeiger

回答

5

當您在一個標準集裝箱使用的類型,比如vector類型必須拷貝構造可分配。如果你的類型有指針成員,那麼這些對於隱式定義的複製賦值操作符都可以正常工作,但引用成員不會這樣做,因爲引用不能被反彈。

如果你想讓你的類型在一個容器中工作,那麼使用指針成員就簡單多了。你是否可以定義一個在你的特定情況下有意義的複製賦值運算符並不明顯,但通常情況並非如此。

0

即使使用用戶定義的賦值運算符,也不能在其中使用引用,因爲引用一旦被初始化就不能被反彈。在這裏使用指針是最簡單的方法。

0

在這種情況下(只有在這種情況下),你可以考慮做B模板..

template <typename SomeA> 
class B{ 
    public: 
     B(string name, SomeA& a):myA(a), name(name){ 
      cout << "Works with reference" << endl; 
     }; 
    private: 
     boost::optional<SomeA&> myA; 
     string name; 
}; 

class A{ 
    public: 
     A(){ 
      cout << "Constructing A" << endl; 
      if(bs.empty()) cout << "Vector is empty" << endl; 
      bs.push_back(B<A>("First", *this)); 
      cout << "Array has " << bs.size() << " elements." << endl; 
     }; 
    private: 
     std::vector<B<A> > bs; 
}; 

這個建議是純粹的,沒有任何背景...