2012-01-27 81 views
2

由於循環依賴的,您可以使用前置聲明對於某些類:是否使用兩個相同的typedef不好,以及如何避免它?

//B.h 
class A; 
class B 
{ 
public: 
    void foo(A* a); 
}; 
typedef SmartPtr<B> BPtr; 

//A.h 
class B; 
class A 
{ 
public: 
    void foo(B* b); 
}; 
typedef SmartPtr<A> APtr; 

現在,讓我們說,我想改變的函數的原型使用智能指針:

void A::foo(BPtr b); 
void B::foo(APtr a); 

很顯然,我不能轉發聲明APtrBPtr。什麼工作是重新使用typedef

//B.h 
class A; 
typedef SmartPtr<A> APtr; 
class B 
{ 
public: 
    void foo(APtr a); 
}; 
typedef SmartPtr<A> APtr; 

//A.h 
class B; 
typedef SmartPtr<B> BPtr; 
class A 
{ 
public: 
    void foo(BPtr b); 
}; 
typedef SmartPtr<A> APtr; 

,但我不知道這是否是正確的解決方案。有沒有這樣做的標準方式?我做錯了還是危險?

回答

3

假設你有一個很好的理由,這些週期性的依賴關係,爲什麼不這樣做:

// defs.h 
class A; 
class B; 
typedef SmartPtr<A> APtr; 
typedef SmartPtr<B> BPtr; 

//B.h 
#include "defs.h" 
class B 
{ 
public: 
    void foo(APtr a); 
}; 

//A.h 
#include "defs.h" 
class A 
{ 
public: 
    void foo(BPtr b); 
}; 
+0

我其實確實想到了這一點,但我認爲存在另一種方式。 – 2012-01-27 13:33:53

+0

你可能在其他方面確實存在。但最好的解決方案往往是最簡單的。 – 2012-01-27 13:38:33

2

在一個共同的頭聲明智能指針和類轉發一次,它包含:

fwd.h :

class A; 
class B; 
typedef SmartPtr<A> APtr; 
typedef SmartPtr<B> BPtr; 

啊:

#include "fwd.h" 

struct A { 
    void foo(BPtr a); 
}; 
2

的問題基本上可以歸結爲這個代碼是否OK:

#include <memory> 

struct A; 

typedef std::unique_ptr<A> APtr; 

struct A {}; 

typedef std::unique_ptr<A> APtr; 

...其中的std ::的unique_ptr可以通過一些其他的智能指針類來代替。

typedef是一個聲明,只要聲明該名稱完全相同,就可以在同一個聲明區域中擁有儘可能多的同名聲明,例如如下所示:

extern int i; 
extern int i; 
extern int i, i, i, i, i, i, i; 

在你的情況下他們這樣做 - 他們都宣稱APTR的別名,標準::的unique_ptr <一個>。 A在一個聲明中是不完整的類型,而在另一個聲明中是完整的並不重要,因爲這個聲明不需要A的完整性(如果是這樣的話,在第一個typedef的位置會出現編譯錯誤) 。

簡而言之:它的工作原理是因爲你不是真正「重複使用」typedef,你只是多次聲明相同的typedef,這很好。

+0

有趣的一點,和+1。但我更喜歡其他答案提出的解決方案。它看起來更清楚。 – 2012-01-27 13:33:18

相關問題