2013-11-25 335 views
0

好吧,我理解前向聲明,但在這種情況下,我需要在兩端調用成員/字段,所以我不能使用它。我嘗試覆蓋.cpp文件中的聲明(通過包含我需要使用的類的實際頭),但是當我嘗試使用它時,通過前向聲明在頭中定義的指針已損壞。循環依賴關係?

我該如何解決這個問題?你需要代碼嗎?

+0

您所描述的相互依存表明存在設計缺陷。重溫您的設計並消除兩種類型之間的緊密耦合。 –

+2

一個SSCCE會很可愛... http://sscce.org/ –

+0

嗯,我有一個事件系統。我也有一個類A,它包含一個B類對象的指針,並管理這個對象。現在我想讓B類發送Events,其中包含一個指向A類的指針。因此,所有類都需要相互瞭解(除了Event類,它只需要知道類A)。 – pixartist

回答

3

您需要注意的是,形成指向類的指針只需要該類的聲明,而訪問該類的成員則需要定義其所以要解決循環依賴,你可以這樣做:

A.hpp

class B; 

class A 
{ 
public: 
    int foo(B *b); 
    int bar(); 
}; 

B.hpp

class A; 

class B 
{ 
    A *m_a; 
public: 
    int foo(); 
    explicit B(A *a) : m_a(a) {} 
}; 

A.cpp

#include "A.hpp" 
#include "B.hpp" 

int A::foo(B *b) 
{ 
    return 2 * b->foo(); 
} 

int A::bar() 
{ 
    return 42; 
} 

B.cpp

#include "A.hpp" 
#include "B.hpp" 

int B::foo() 
{ 
    return m_a->bar(); 
} 
+0

我試過,但指針無效(內存異常) – pixartist

+0

AHH!你是對的,我錯了一個變量! – pixartist

0

如果您是唯一一個可以訪問代碼內部的人(例如,當您爲自己完成項目,單獨執行或分發已關閉的10.lib/.dll時)和您'當然你需要你的類以循環方式包含自己,你總是可以使用抽象基類。

class base{}; 

class A: public base{ 
    base *bMember; 
}; 

class B: public base{ 
    base *aMember; 
}; 

這是一個不好的做法,但如果您需要一個直接的解決方案,它應該是足夠的。更好的方法是修復依賴關係或使用單獨的基類。

+0

即使他真的需要這樣做,爲什麼不會轉發聲明足夠了嗎?我沒有看到抽象基類的觀點。 –

+0

一些較老的IDE傾向於忽略前向聲明。很久以前我在某個版本的VS上做項目時遇到過這樣的問題。 –