2013-03-24 56 views
1

我讀過很多循環依賴主題,但找不到解決我的問題的主題。我有一個包含指向彼此兩類:C++在構造函數中循環指針注入

class B; 

class A 
{ 
public: 
    A(B* _b, int _c): b(_b), c(_c) {} 
    B* b; 
    int c; 
}; 

class B 
{ 
public: 
    B(A* _a, int _d): a(_a), d(_d) {} 
    A* a; 
    int d; 
}; 

的問題是,在下面的代碼:

class C 
{ 
public: 
    A* a_ptr; 
    B* b_ptr; 
    C() 
    { 
     a_ptr = new A(b_ptr, 3); 
     b_ptr = new B(a_ptr, 2); 
     qDebug() << a_ptr->c; 
     qDebug() << b_ptr->d; 
     qDebug() << a_ptr->b->d; 
     qDebug() << b_ptr->a->c; 
    } 
} 

最後兩行是崩潰的應用程序。我瞭解問題和崩潰的原因。我可以爲成員編寫setter,並在創建對象後調用它們,因此指針將是有效的。但是,我希望在調用構造函數之後完成對象,而不用調用任何其他方法。

所以...我想知道是否有任何方法在構造函數中注入(循環)指針?

回答

2

你可以讓一個構造器完成其他對象的初始化:

B(A* a_ptr) : a(a_ptr) 
{ 
    if(a) 
     a->b = this; 
} 
A()

與相同。因此,你可以像下面創建它們:

a_ptr = new A(b_ptr, 3); // b_ptr was initialized to 0 
b_ptr = new B(a_ptr, 2); // b_ptr->a = a_ptr 
         // b_ptr->a->b = b_ptr (ie, a_ptr->b = b_ptr) 

編輯:正如評論指出,這是不可伸縮的,如果你有很多類。但是,在一般情況下,您將不得不初始化構造函數的之外的循環依賴,其次,您不應該有很多循環依賴於對方的類(如果是這種情況,也許可以重新排列代碼。 ..)。

+1

如果你添加了幾個所有相互依賴的類,該怎麼辦?這種方法可以在簡單的情況下工作,但從長遠來看它是難以管理的。簡單的例子是,如果其他開發人員先做出B然後再做出A?這就是說,解決OP。 – 2013-03-24 12:43:39

+0

我同意,這是不可擴展的。然而,OP沒有解決方案,這是創建對象的唯一方法,只有使用構造函數創建對象,創建後沒有初始化代碼... – Synxis 2013-03-24 12:48:16

+0

這在技術上不是真實的,B正在對A進行第二次初始化, - > b_ptr = this。即A的狀態不是通過它自己的構造函數完成的。它需要第二次初始化,你剛剛隱藏在B中。 – 2013-03-24 12:49:40