2012-04-21 37 views
4

將聲明轉發到另一個頭文件中合法嗎?例如:在另一個文件中轉發聲明C++

#ifndef _MAIN_H_ 
#define _MAIN_H_ 
class ClassA; 
class ClassB; 
#include "classa.h" 
#include "classb.h" 
#endif 

#ifndef _CLASSA_H_ 
#define _CLASSA_H_ 
#include "main.h" 
class ClassA 
{ 
public: 
    ClassB b; 
}; 
#endif 

#ifndef _CLASSB_H_ 
#define _CLASSB_H_ 
#include "main.h" 
class ClassB 
{ 
public: 
    ClassA a; 
}; 
#endif 

A類和B類都相互依賴,並且都有另一種類型的對象。我所做的是在另一個文件中向前宣佈這兩個類。有沒有一種乾淨的方式來做到這一點?

+1

你需要打破這個循環。試着想想如果你試圖創建一個A的實例會發生什麼(創建A,需要創建一個B,需要爲它創建一個A,需要創建一個B,...) – Mat 2012-04-21 18:10:35

+0

這就是耦合。不是嗎?你爲什麼需要對方的定義?具體的例子?如果它們的功能如此相似,你可以將它們變爲子類嗎? – CppLearner 2012-04-21 18:11:04

+0

@CppLearner「你爲什麼需要對方的定義?」我的錯誤 – user52343 2012-04-21 18:17:05

回答

3

一般來說,在頭文件中前向聲明類是合法的。

但是,在你的例子中,你正在相互實例化兩個類,這是絕對非法的!

爲了證明這背後的推理,思考以下幾點:

ClassA取1個字節沒有bClassB也是1個字節沒有a。 現在,包含bClassA現在需要2個字節。現在包括aClassB現在需要3個字節。現在我們必須將ClassA的大小更新爲4個字節,這是由於大小增加了ClassB。以下是邏輯ClassB現在是5個字節,ClassA 6個字節,ClassB 7字節.......

爲了解決這個問題,你可能想改變的類型ab(至少一個)指向相應類的指針或引用。當這樣做時(以​​c/C++),確保你理解你的內存管理!

解決您的原始問題,那麼可以看看如下:

ClassA.h

#pragma once 
class ClassB; 
class ClassA 
{ 
public: 
    ClassB* b; 
} 

ClassB.h

#pragma once 
#include "ClassA.h" 
class ClassB 
{ 
public: 
    ClassA a; 
} 

注意ClassB.h需要ClassA.h自用於演示目的:ClassB包含類型爲ClassA的完整對象,因此需要定義ClassA

3

是的。但是,您應該使用ClassA* a;ClassA& a;而不是ClassA a;(在cpp文件中具有相應的初始化) 因爲沒有關於計算大小ClassA的信息來計算大小ClassB