2013-05-15 29 views
2

我有兩個類,可以說A類和B類。我的目標是讓這兩個類使用eachothers函數。問題是,多文件包含結構似乎沒有讓我這樣做。這裏就是我想要做的事:使用eachother的C++類

#file A.h 

Class A{ 
public: 
    int GetInfo(); 

private: 
    B * ptrToB; 
}; 

#file B.h 

Class B{ 
public: 
    int getStuff(); 
private: 
    A * ptrToA; 
}; 

我的目標是一個A類方法能夠調用ptrToB->getStuff()和B類方法能夠調用ptrToA->getInfo()

這可能嗎?怎麼會這樣?如果不是,爲什麼不呢?

+1

其他人指出了讓它編譯的方法,但問問自己爲什麼你的類需要如此耦合。要麼讓它成爲一個班級,要麼把正確的數據放在正確的班級上。不要使用getter。用這些數據告訴班級做正確的事情。查找[數據嫉妒](http://c2.com/cgi/wiki?DataEnvy)等。 –

+0

[相互遞歸類](http://stackoverflow.com/questions/3410637/mutually-recursive-classes) – ecatmur

回答

4

也許使用前向聲明?

#file A.h 

#ifndef ACLASS_H 
#define ACLASS_H 

Class B; 

Class A{ 
public: 
    int GetInfo(); 

private: 
    B * ptrToB; 
}; 

#endif 

然後在CPP文件中。

#file A.cpp 

#include "B.h" 

A::A() : ptrToB(0) 
{ 
    // Somehow get B 
} 

int A::GetInfo() 
{ 
    // Return whatever you need in here. 
} 

同樣的事情會爲B類H和CPP文件來完成。

正向定義允許編譯器識別一個類型,而不需要明確定義它。如果你在A班有一個B的參考,你將不得不包含B的標題。

由於您正在使用指針訪問B,編譯器在訪問它之前(在CPP文件中)不需要知道內部數據。

// Would need the header because we must know 
// the size of B at compile time. 
class B; 
class A 
{ 
    B theB; 
} 


// Only need forward declaration because a 
// pointers size is always known by the compiler 
class B; 
class A 
{ 
    B * bPointer; 
} 
+0

另一個好的答案。 – RandyGaul

+0

謝謝,它的工作原理!我早些時候嘗試過,除了我嘗試從B.h文件中的內聯函數調用aPointer-> AMemberFunc()。我猜這個關鍵是頭文件中的前向聲明,後面是包含在.cpp文件中的內容?這是專門避免循環依賴嗎? – Nathan

+0

是的,你可以做到這一點,要麼隱藏的東西的實施,並避免循環依賴。 –

2

只需添加一個向前聲明文件A.H,所以編譯器知道一個B*是一個指向類,你將定義以後:

class B; 

再經過了定義class A和包括B.h。這樣,包括A.h在內的任何人都將定義class Aclass B

在B.h剛剛包括A.h在開始。這樣,包括B.h在內的任何人都將同時定義class Aclass B

當您在關聯的.cpp文件中定義函數時,您將擁有兩個類,並且可以根據需要編寫函數。這個問題叫做mutual recursion

+0

的可能重複,用於解釋,而不僅僅是準備使用的代碼......(當然這是也沒關係;))很好的答案。 – leemes

2

您可以使用前置聲明打破依賴關係:

#file A.h 

Class A{ 
public: 
    int GetInfo(); 

private: 
    B * ptrToB; 
}; 

#file B.h 
struct A; 
Class B{ 
public: 
    int getStuff(); 
private: 
    A * ptrToA; 
}; 

那麼您可以在B.cpp和B.h在A.cpp A.h沒有問題。