2009-12-14 33 views
0

有沒有辦法在頭文件中聲明這些類而不間接?聲明不帶指針的默認參數循環引用?

// Forwards declaration of B 
class B; 

class A 
{ 
public: 
    // Default parameter referring to B. May return its parameter 
    const B& func(const B& b = B()); 
}; 

class B 
{ 
public: 
    // B ctors 
    B() {} 
    B(const B&) {} 

    // B has A as a member 
    A a; 
}; 

的Visual C++ 2008告訴我這件事:

error C2514: 'B' : class has no constructors 

和點B的前向聲明( 「B類」;),顯然不能見下文B的構造函數。 A不能跟隨B,因爲B包含A作爲成員。

如果必須使用間接方式,那麼最好的方法是什麼?也許在C++ 0x B的A可能是一個unique_ptr成員?或者也許純粹是爲了迴避這個問題而增加一個強化班?

回答

7

而不是一個默認參數聲明兩個重載,一個參考B和一個不參數。在不採用參數的情況下,使用B()來調用另一個,這將起作用,因爲可以在定義B之後定義該方法。

... 
    void func(); 
    void func(const B& b); 
}; 

class B... 

void A::func() { func(B()); } 
void A::func(const B&) { } 

更新:

FUNC()返回一個const乙& ......

這可能不是一個好主意。有了這個定義,是這樣的:

const B& foo = a.func(); 
foo.bar(); 

會因爲B到你有一個參考值將盡快第一個語句是完全破壞導致可怕的「未定義行爲」(即崩潰)。通過引用返回除班級成員之外的東西通常是一個糟糕的主意。

如果你真的想這樣做,那麼我認爲你堅持強制調用者明確地通過B(),即沒有默認參數。

a.func(B()).bar(); 

(這是爲了避免與這樣的功能未定義行爲的唯一途徑。)

當然,你可以只返回一個副本,而不是一個參考,但我相信你有沒有這樣做的理由那。

根據你在做什麼,你可以使用像shared_ptr這樣的智能指針代替引用來設置更好的語義,這樣就可以有效地忽略對象的生存期。但是,您必須開始小心參考循環。

我不能說出你想要用什麼,但你可能想看看Design Patterns看看是否有一個確定的最佳實踐。你可能會發現這個小問題是一個不幸選擇階級結構或遏制的症狀。

+0

感謝您的回答。這會工作,但我忘了提及 - func()返回一個常量B&,並可能返回它的參數,所以沒有參數的版本是沒有意義的。然後怎樣呢? – AshleysBrain 2009-12-14 00:18:32