1

VS2010 でソリューションをビルドしようとすると、不可解なコンパイラ エラーが発生します。これらのインクルードがどのように機能するかを理解するのに本当に苦労しています。

Game.cpp
Game.h
Deck.cpp
Deck.h
Card.h

// Game.cpp
#include "Game.h"

すべて良い。次に、新しいデッキを作成する必要があります。

// Game.h
private:
    static Deck _deck;

それでは、Deck.h をインクルードして、それが何であるかを認識させる必要があります。

// Game.h
#include "Deck.h"
class Game {
private:
    Deck _deck;
}

わかりました。しかし、今は Game.cpp で _deck を使用する必要があります

// Game.cpp
#include "Game.h"
Deck Game::_deck;
void Shuffle(void)
{
     _deck = Deck();
     _deck.Shuffle();
}

しかし、「デッキが定義されていません」というエラーが表示されます。しかし、Game.cpp には Game.h が含まれているので、Game.h には Deck.h を含める必要がありますか?

Deck.h を Game.cpp に追加すると、次のようになります。

"Uses undefinied class Deck Game.cpp"

"Deck class redeclaration Deck.h"

これが全然わからない…

4

3 に答える 3

2

インクルードガードを説明するこのstackoverflowの質問が表示されるはずです

#ifndef と #define が C++ ヘッダー ファイルで使用されるのはなぜですか?

于 2013-02-25T23:42:25.257 に答える
1

循環インクルードがあります。幸いなことに、staticメンバーは宣言時に完全な定義を必要としないため、前方宣言を使用して Game.h に含めることができます。

// Game.h
class Deck;

//....
private:
    static Deck _deck;
于 2013-02-25T23:43:54.563 に答える
1

#includeコンパイラの前に実行され、基本的にテキストの置換を実行するプリプロセッサ フェーズの一部です。

あなたが説明する問題は、翻訳単位に関係しています。基本的に、ソース ファイル (.c、.cpp、.inl など) はヘッダー ファイル (.h、.hpp) とは異なると考えることができます。各ソース ファイルは、コンパイラが変換できる翻訳単位を定義しているからです。運営する。ソース ファイルは、基本的に、ファイル内のすべてのロジックと、それが直接的または間接的に参照するすべてのインクルードで構成されます。

コンパイラは、各翻訳単位からオブジェクト ファイルを構築し、リンカーの仕事として、それらをすべてライブラリまたは実行可能バイナリにまとめます。他のソース ファイル内のロジックは、リンク時まで、他のソース ファイルまたはヘッダーですぐには使用できません。

最も覚えやすいのは、ヘッダー ファイルがインターフェイスを定義し、ソース ファイルが実装を定義していることです。コンパイル時間の速度を上げ、オブジェクト間の結合を緩めるために、ヘッダー ファイルをできるだけ軽くし、実装の詳細をできる限り排除する必要があります。これを行うには、ヘッダー ファイルの前方宣言に依存し、他のヘッダー ファイル内の .h 参照を最小限に抑え、代わりにそれらをソース ファイルに移動します。

多くの最新の言語では、インターフェイスと実装という 2 つの概念が混在していますが、新しい IDE の機能により、これは大きな問題ではありません。ただし、このアプローチははるかに明示的であるため、C ++での分離を今でも振り返って感謝しています。適切に作成されたクラスのクライアントは、実装の詳細を無視できる必要があるため、クラスを使用するために表示する必要があるのはヘッダーだけです。C++ でライブラリを扱っている場合、ヘッダー ファイルにしかアクセスできない可能性があるため、これはよくあることです。

于 2013-02-25T23:54:53.273 に答える