8

私はプログラミングを始めたばかりで、ヘッダーファイルをたくさん使い始めた後、ヘッダーファイルのトピックは私を行き詰まらせています。それに加えて、プリコンパイル済みヘッダーを使用しようとしています。私はSFMLライブラリも使用しているので、それらのヘッダーも含める必要があります。

現在、stdafx.h、main.cpp、クラス A、B、C、および D が Ah、A.cpp、Bh、B.cpp、Ch、C.cpp、Dh、および D.cpp に含まれています。

次の場合、すべてのファイルにヘッダーを含める順序はどれですか

  • すべてのクラスは SFML クラスのインスタンスを含みます
  • クラス D には、クラス A とクラス C のインスタンスが含まれています
  • クラス C にはクラス B のインスタンスが含まれています。私のコード: (注: すべてのヘッダーにはヘッダー ガードがあります)

stdafx.h:

#include <SFML/Graphics.hpp>
#include <iostream>

ああ

#include "stdafx.h"
class A
{
    //sfml class
};

A.cpp

#include "stdafx.h"
#include "A.h"

Bh

#include "stdafx.h"
class B
{
    //sfml class
};

B.cpp

#include "stdafx.h"
#include "B.h"

チャンネル

#include "B.h"
class C: public B
{

};

C.cpp

#include "stdafx.h"
#include "C.h"

Dh

#include "A.h"
#include "C.h"
class D
{
    A a;
    C C; // if left uncommented I recieve a '1 unresolved externals' error
    //sfml class
}

D.cpp

#include "stdafx.h"
#include "D.h"

main.cpp

#include "stdafx.h"
#include "D.h"
4

5 に答える 5

10

私の哲学は、適切に記述されたコードでは、ヘッダー ファイルには、依存する他のすべてのヘッダー ファイルを含める必要があるというものです。私の推論は、ヘッダー ファイルをインクルードしてコンパイル エラーを発生させることはできないはずだということです。したがって、各ヘッダー ファイルには、( #ifdefor #pragma once include guardの後に) 依存する他のすべてのヘッダーを含める必要があります。

ヘッダー ファイルに正しいヘッダーをインクルードすることを忘れていないことを非公式にテストするために、*.cpp ファイルは、機能するヘッダー ファイルの最小セットを #include する必要があります。したがって、ABCおよびの個別のヘッダー ファイルがDあり、cpp ファイルが classを使用している場合は、 DhDのみを含める必要があります。Dh s AhChChにはBhが含まれ、AhBhには SFML ヘッダー (それが何であれ) が含まれるため、コンパイラ エラーは発生しません。ChDh #include適切と思われる場合は SFML ヘッダーを含めることができますが、依存関係 ( BhおよびAh ) に既に含まれていることが確実な場合は、実際には必要ありません。

ただし、Visual C++ が「プリコンパイル済みヘッダー」を行う方法は、このロジックを台無しにします。最初のヘッダー ファイルとしてインクルードする必要"StdAfx.h"があるため、多くの開発者は#includeプロジェクト全体のすべての s をStdAfx.h#includeに単純に配置し、他のヘッダー ファイルでは使用しません。これはお勧めしません。または、すべての外部依存関係を StdAfx.h (例: windows.h、ブースト ヘッダー) に配置し、ローカル依存関係を別の場所に #include して、1 つのヘッダー ファイルを変更してもプロジェクト全体が必ずしも再構築されないようにします。

私のコードの書き方では、ほとんどの CPP ファイルに StdAfx.h と対応する .H ファイルが含まれています。したがって、A.cpp には StdAfx.h と Ah が含まれ、B.cpp には StdAfx.h と Bh が含まれます。cpp ファイルに配置される他の唯一の#includeは、ヘッダー ファイルによって公開されない「内部」依存関係です。たとえば、クラスが をA呼び出す場合printf()Ahはstdio.hに依存しないため、( Ahではなく) A.cppが を呼び出します。#include <stdio.h>

これらのルールに従えば、#includeヘッダーの順序は問題になりません(プリコンパイル済みヘッダーを使用しない限り: プリコンパイル済みヘッダーは各 cpp ファイルの最初に来ますが、ヘッダー ファイルからインクルードする必要はありません)。

于 2011-04-05T23:22:29.853 に答える
1

同様の質問を見て、ヘッダーを作成するための適切なアプローチを学んでください。

つまり、コンパイル中にヘッダーが複数回含まれないようにする定義ガード内で各ヘッダーを定義する必要があります。これらを配置したら、.h および .cpp ファイルごとに、宣言を解決するために必要なヘッダーを含めるだけです。プリプロセッサとコンパイラが残りを処理します。

于 2011-04-05T22:54:00.147 に答える
1

CはクラスBを継承します。したがって、識別子が表示されるはずBです。だから、B.hここに含めてください -

#include "B.h"    // Newly added
// Or you can forward declare class B ; 
class C: public B
{

};

DAには、クラス、のオブジェクトがありますB。したがって、A, B「Dh」自体にヘッダーを含めます。

class D
{
    A a;  // Should see the definition of class A
    C c;  // Should see the definition of class B
    //sfml class
}

D.cpp

#include "A.h"
#include "C.h"
#include "D.h"  // Notice that A.h and C.h should definitely placed before

すべてのヘッダーは、対応するソース ファイルに含める必要があることに注意してください。各ソース ファイルを個別に考えて、これまでに使用されたものがソース ファイルで以前に定義されているかどうかを確認します。

于 2011-04-06T01:04:11.937 に答える
1

ああ、SFML を含める必要があります

A.cpp には Ah を含める必要があります

Dh には SFML、Ah、および Ch を含める必要があります

D.cpp には Dh を含める必要があります

main.cpp には、直接使用する A、B、C、D、および SFML のいずれかを含める必要があります。

一般に、.cpp ファイルには、対応する .h に含める必要があることがわかっているヘッダーは含めません。ヘッダーには、その .h で定義されたクラスのデータ メンバーの定義が含まれているためですしたがって、私のコードでは、D.cpp には Ah That's just me は含まれませんが、.cpp ファイル (おそらく) が使用していることを思い出させるために、とにかくそれを含めることをお勧めします。

これによりstdafxが残ります-これが必要な場所は、その中のものを使用するものによって異なります。おそらくどこでも必要であり、MSVC はソース ファイルの前に何も処理しない (または処理するが破棄する?)#include "stdafx.h"ため、各 .cpp ファイルの最初のものであり、他の場所には表示されません。

すべてのヘッダー ファイルには、複数のインクルード ガードが必要です。

SFML (または他の好きなもの) を stdafx.h に追加できます。その場合、それらのインクルードを他の場所から削除することもできます。

これが完了すると、各ファイルにヘッダーを含める順序は重要ではなくなります。したがって、好きなことを行うことができますが、stdafx.h を考慮して調整された、件名に関するGoogle の C++ スタイル ガイド(矢印をクリック) をお勧めします。

于 2011-04-05T22:56:41.050 に答える
0

依存関係に依存します。C# や他の同様の言語とは異なり、C++ は記述された順序で処理を行うため、問題が発生する可能性があります。順序に問題がある場合は、コンパイルされません。

于 2011-04-05T23:14:56.620 に答える