[解決済み] .h ファイルで #ifndef CLASS_H と #define CLASS_H を使用し、.cpp で使用しない理由は何ですか?
質問
と書いている人をよく見かけます。
class.h
#ifndef CLASS_H
#define CLASS_H
//blah blah blah
#endif
問題は、クラス関数の定義を含む.cppファイルについても、なぜそうしないのか、ということだ。
例えば
main.cpp
と
main.cpp
には
class.h
. その
class.h
ファイルでは
include
はどのように
main.cpp
の中に何があるのかを知っています。
class.cpp
?
解決方法は?
まず、最初のお問い合わせに対応します。
に表示されている場合 .h ファイルを作成します。
#ifndef FILE_H
#define FILE_H
/* ... Declarations etc here ... */
#endif
これは、様々な理由で問題となるヘッダーファイルの複数回インクルードを防ぐためのプリプロセッサー技術です。 プロジェクトのコンパイル時に、それぞれの
.cpp
ファイルが(通常)コンパイルされます。 簡単に言うと、これはコンパイラがあなたの
.cpp
ファイルを開き、任意のファイル
#included
そして構文解析を行い、最終的に中間コードに変換し、最適化/その他のタスクを実行し、最終的にターゲットアーキテクチャ用のアセンブリ出力を生成するのです。 このため、もしファイルが
#included
1つの
.cpp
そのため、そのファイル内に定義がある場合、変数を再定義したというコンパイラーエラーが発生します。 このファイルがコンパイルプロセスのプリプロセッサのステップで処理されるとき、最初にその内容に到達したとき、最初の2つの行は、もし
FILE_H
がプリプロセッサーに定義されています。 もしそうでなければ
FILE_H
との間のコードを処理し続けます。
#endif
ディレクティブを使用します。 次にそのファイルの内容がプリプロセッサに表示されたときに
FILE_H
は false になるので、すぐに
#endif
の後に続けてください。 これにより、再定義エラーを防ぐことができます。
そして、2つ目の懸念に対応するためです。
C++のプログラミングでは、一般的に開発物を2つのファイルタイプに分けます。 1つは、拡張子が .h ヘッダーファイルは、通常、関数、クラス、構造体、グローバル変数、型定義、プリプロセッシングマクロ、定義などの宣言を提供します。 基本的に、ヘッダーファイルはコードに関する情報を提供するだけです。 次に .cpp このファイルには、関数、クラス・メンバー、定義が必要な構造体メンバー、グローバル変数などの定義が含まれます。 そのため .h ファイルはコードを宣言し .cpp ファイルはその宣言を実装しています。 このため、一般にコンパイル時には、それぞれの .cpp ファイルをオブジェクトに変換し、それらのオブジェクトをリンクします(なぜなら、1つの .cpp ファイルには、別の .cpp ファイル)を作成します。
これらの外部参照をどのように解決するかは、リンカーの仕事である。 コンパイラが main.cpp のコードに対する宣言を取得します。 クラス.cpp を含むことで class.h . 関数や変数がどのようなものかを知るだけでよいのです(これは宣言が与えてくれるものです)。 そのため main.cpp ファイルを何らかのオブジェクトファイル(これを main.obj ). 同様に class.cpp がコンパイルされ class.obj ファイルを作成します。 最終的な実行ファイルを作成するために、リンカーが起動され、これら2つのオブジェクトファイルを一緒にリンクします。 未解決の外部変数や関数がある場合、コンパイラはアクセスが発生する場所にスタブを配置します。 そして、リンカーはこのスタブを使って、リストアップされた別のオブジェクトファイルからそのコードや変数を探し、見つかった場合は、2つのオブジェクトファイルからコードを出力ファイルに結合し、スタブを関数や変数の最終位置に置き換えます。 このようにして、main.cpp のコードは、関数呼び出しや変数使用のために class.cpp で宣言されている場合のみです。 class.h .
参考になったでしょうか?
関連
-
[解決済み】coutはstdのメンバではない
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] template "と "typename "キーワードはどこに、なぜ入れなければならないのですか?
-
[解決済み] C++テンプレート関数定義の.CPPファイルへの格納
-
[解決済み] C++のヘッダーファイルで#ifndefと#defineが使われているのはなぜですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】識別子 "string "は未定義?
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】C++の余分な資格エラー
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み] C++のヘッダーファイルで#ifndefと#defineが使われているのはなぜですか?