2012-01-25 20 views
1

私はコードがうまくいきません。 b.cppでは、クラスBはクラスAを使用しますが、クラスAの宣言が見つからないため失敗します。 ただし、a.hppは直前に含まれています。 #include "a.hpp"がここで動作しないのはなぜですか?ヘッダーには循環的な依存関係が含まれています

ありがとうございました!

//=============================================== 
//file: a.hpp 
//=============================================== 
#ifndef _A_HPP 
#define _A_HPP 

#include "b.hpp" 

class A{ 
    public: 
     A(); 
     // others methods using B here 
}; 

#endif 


//=============================================== 
//file: a.cpp 
//=============================================== 
#include "a.hpp" 

A::A(){} 


//=============================================== 
//file: b.hpp 
//=============================================== 
#ifndef _B_HPP 
#define _B_HPP 

#include "a.hpp" 

class B{ 
    public: 
     B(A a); 
}; 

#endif 
//=============================================== 
//file: b.cpp 
//=============================================== 
#include "b.hpp" 

B::B(A a){} 



SHELL$ g++ -c a.cpp 
In file included from a.hpp:7, 
       from a.cpp:4: 
b.hpp:11: error: expected ‘)’ before ‘a’ 

答えて

2

あなたは、このような循環依存関係を壊すためにForward declarationsを使用する必要があります。
ただし、フォワード型を宣言すると、そのタイプは、コンパイラの不完全な型になり、あなたがから

#include "b.hpp" 

を削除不完全なタイプ

0

を使用する方法に制限があることに注意してくださいa.hとだけは前方宣言を持っている - あなたはABへのポインタを使用すると仮定すると:

//A.hpp 

class B; //forward declaration 

class A{ 
    public: 
     A(); 
     // others methods using B here 
}; 

アンダースコアで始まるマクロ名_は標準で予約されているため、使用しないでください。 _B_HPPを単にB_HPPに置き換えてください。

+0

を宣言転送することができ、私はの#includeを考えていた – user744629

0

なぜサイクリック#includeが必要ですか?あなただけの存在(それがエトセトラパラメータとすることができる)クラスを知っているコンパイラのために必要がある場合は、ちょうど前方にこのようにそれを宣言します。

class A; 

は周期的にファイルを含めないでください。警備員がいても、それらは両方とも一度だけ確実に組み込まれますが、コンパイラがその定義に達する前にAの言及に入るか、またはBという言葉になるとコンパイラはその定義になります。本当にあればラインB(A a)に、コンパイラはA.

について知らないので、プリコンパイラは、ファイルの内容を無視するよう

+0

_についての良い発言のためのおかげで、コードを複製し、maintenaceは簡単ではないし、良好でした。でも、重複したコードは単なる「クラスA」です。実際の長いソースコードではあまり長くはならないはずです... – user744629

0

b.hppはa.hppを含み、_A_HPPはすでに、定義されていますこれらが含まれている必要がある場合は、#include "b.hpp"a.hppの末尾に移動してください(またはclass A;の頭にb.hppと記載してください)。

+0

私はすべてが大きなファイルに入っていると思っていましたが、最終的にa.cpp + a.hpp + b.hpp – user744629

+0

b.hpp + aのようになります.hpp + a.cpp – asaelr

0

A.hppには、Bのメソッドを呼び出すB.hppまたはインラインAの実装は含めないでください。

B&またはB*を参照する必要がある場合は、A.hpp(前方宣言)にclass B;を使用してください。

代わりに、A.cppでBメソッドを呼び出し、A.cppにB.hppを含む実装を実装します。

1

これは機能しません。ヘッダーファイルには、他のクラスへの参照またはポインタのみを含めるようにしてください。そして、あなたはAまたはB、例えば:

//=============================================== 
//file: b.hpp 
//=============================================== 
#ifndef _B_HPP 
#define _B_HPP 

class A; 

class B{ 
    public: 
     B(A& a); 
}; 

#endif 
関連する問題