2017-09-01 11 views
0

私は "この特定のケース"では "あなた"がそのクラスへのポインタしか使用していないので、完全なクラス定義は必要ではないと言っている依存関係を含みます。円は依存関係/フォワード宣言を含みます

この問題が発生し、フォワード宣言を使用して修正されました。

私は、両方のクラスで他のクラスの特定の定義が必要なときに何をすべきか考えています。

また、クラスへのポインタを使用すると、クラス定義の代わりに前方宣言を使用できますか?

答えて

2

どのような場合には、両方のクラスについて事前に知られている仕様が必要ですか?

class A 
{ 
    B m_b; 
}; 

class B 
{ 
    A m_a; 
}; 

しかし、クラスAのサイズは、クラスBの大きさに依存するので、これは不可能ですが、クラスBのサイズは、クラスAのサイズによって異なります。

一つ不可能な場合は、以下のとおりです。どちらかを作成しようとすると、無限の系列A myA; myA.m_b.m_a.m_b.m_a....も得られます。

ポインタを使用する場合は、ポインタのサイズを知る必要はありません。ポインターは、あなたのプラットフォームに応じて常に同じサイズです。ヒープ内のオブジェクトを明示的に作成する必要があるため、シリーズは消えます。

+0

私は考えていた例では、オブジェクトである「」オブジェクト「B Bを」作成するが、建設に又は道をいくつかの時点でいずれかのそれ自体のコピーを渡します。しかし、「オブジェクトBは、」私はあなたがその中には、貧しい人々のプログラミングを検討することになるだろうどのような状況かなり確信しているタイプA のメンバ変数を持っているが、それは私を悩ませた問題でした。 総合的な回答ありがとうございます! – Spectral

+0

"コピーを渡します" - パラメーターまたは戻り値の型としてvalueで渡された不完全なクラスを持つ関数を宣言できます。クラス定義が完了するまでそれを定義したり呼び出すことはできません。だから 'クラスA;クラスB {public:void process(A); }; '大丈夫です。 (そこにさえ、 'const A&'を使うかもしれません。) – aschepler

0

両方のクラスで特定の という特定の定義が必要な場合は、どうしたらいいでしょうか。

最新のコンパイラでは、前方宣言と遅延定義を使用して実行できます。多くの古いコンパイラでは、宣言された型を転送するための参照だけがポインタ&で許可されています。

ここでは不自然な例です:

A.hpp

class B; 

class A 
{ 
public: 
    int32_t Value; 

    A(int32_t value) : Value(value) { } 

    int32_t Add(B b) const; 
} 

B.hpp

#include "A.hpp" 

class B 
{ 
public: 
    int32_t Value; 

    B(int32_t value) : Value(value) { } 

    int32_t Sub(A a) const; 
} 

AB.hpp

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

inline int32_t A::Add(B b) const 
{ 
    return this->Value + b.Value; 
} 

inline int32_t B::Sub(A a) const 
{ 
    return this->Value - a.Value; 
} 

また、クラス定義の代わりに前方 宣言を使用できるように、クラスへのポインタを使用するのはなぜですか?

フォワード宣言は、コンパイラの名前に過ぎません。この概念は、定義されていない型を使用できるように存在します。まだです。これは、C++がコードをパーズする方法、それが大量に継承するC言語の成果物のために必要です。 C++のパーサーは、実際には、#includeとマクロを使用すると、テキストを挿入する前方転送専用のテキストプロセッサです。概念的にはシンプルなモデルなので、C/C++コンパイラは初期の段階で書きやすくなりました。これをC#/ Javaと比較すると、単に/ importを使用して簡単な構文でクラス間の循環依存関係を作成することができます。

ポインタは実際にはshortおよびintに似た整数ですが、CPUアーキテクチャに基づいてコンパイル時に知られている固定サイズと言語によって強制される特別なセマンティクスを備えています。これにより、コンパイラが対処するポインタ宣言が非常に簡単になります。

前方宣言は、循環依存性と実装隠蔽を容易にします(コンパイル時間のスピードアップも起こります)。 pimpl idiomを考えてみましょう。前方宣言がなければ、実装の詳細を隠すための型安全な方法はありません。

関連する問題