[解決済み] C++のヘッダーファイルはどのように実装を含めることができますか?
質問
C/C++の専門家ではありませんが、ヘッダーファイルのポイントは関数を宣言することであり、C/CPPファイルは実装を定義することだと思っていました。
しかしながら、今夜いくつかの C++ コードを見直したところ、クラスのヘッダーファイルでこれを見つけました...。
public:
UInt32 GetNumberChannels() const { return _numberChannels; } // <-- Huh??
private:
UInt32 _numberChannels;
では、なぜヘッダーに実装があるのでしょうか?それは
const
キーワードと関係があるのでしょうか?クラスメソッドをインライン化するのでしょうか?この方法で行うことの利点/ポイントは、CPP ファイルで実装を定義することと比較して、正確には何ですか?
どのように解決するのですか?
OK、決してC/C++の専門家ではありませんが、ヘッダーファイルのポイントは関数を宣言することであり、次にC/CPPファイルは実装を定義することだと考えていました。
ヘッダーファイルの真の目的は、複数のソースファイル間でコードを共有することです。 それは
一般的に
宣言と実装を分離してコード管理をしやすくするために使用されますが、これは必須ではありません。 ヘッダファイルに依存しないコードを書くことは可能ですし、ヘッダファイルだけで構成されたコードを書くことも可能です(STLやBoostライブラリはその良い例です)。 覚えておいてほしいのは
プリプロセッサー
に遭遇したとき
#include
文に出会うと、その文を参照されているファイルの内容に置き換えます。
コンパイラ
は完成した前処理されたコードだけを見ることになります。
ですから、例えば次のようなファイルがあったとします。
Foo.h:
#ifndef FooH
#define FooH
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
#endif
Foo.cppです。
#include "Foo.h"
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cppです。
#include "Foo.h"
Foo f;
UInt32 chans = f.GetNumberChannels();
この プリプロセッサー は Foo.cpp と Bar.cpp を別々に解析し、以下のコードを生成します。 コンパイラ がパースします。
Foo.cppを解析します。
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cppです。
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
Foo f;
UInt32 chans = f.GetNumberChannels();
Bar.cppはBar.objにコンパイルされ、以下を呼び出すための参照を含んでいます。
Foo::GetNumberChannels()
. Foo.cppはFoo.objにコンパイルされ、以下の実装が含まれます。
Foo::GetNumberChannels()
. コンパイル後
リンカ
は .obj ファイルをマッチングし、最終的な実行ファイルを生成するためにそれらをリンクします。
では、なぜヘッダーに実装があるのでしょうか?
メソッド宣言の中にメソッドの実装を含めることで、暗黙のうちにインライン化を宣言していることになります(実際には
inline
キーワードを明示的に使用することもできます)。 コンパイラが関数をインライン化するよう指示することは、その関数が実際にインライン化されることを保証しないヒントに過ぎません。しかし、インライン化された場合、インライン化された関数がどこから呼び出されても、関数の内容は
CALL
ステートメントを生成して関数に飛び込み、終了時に呼び出し元にジャンプバックするのではなく、関数の内容が呼び出し元に直接コピーされます。 これにより、コンパイラーは周囲のコードを考慮し、可能であればコピーされたコードをさらに最適化することができます。
constキーワードと関係があるのでしょうか?
いいえ。
const
キーワードは単に、そのメソッドが実行時に呼び出されるオブジェクトの状態を変更しないことをコンパイラに示すだけです。
CPPファイルで実装を定義するのに対して、この方法で行う利点/ポイントは正確に何ですか?
効果的に使用すると、通常、コンパイラーはより速く、より最適化されたマシン・コードを生成することができます。
関連
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] Linux上で動作するC++コードのプロファイリングを行うにはどうすればよいですか?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み] なぜC++のインライン関数はヘッダーにあるのですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み] externとconstの混在
-
[解決済み】C++の定義をヘッダーファイルに配置するのは良い習慣ですか?
-
[解決済み] インライン変数の仕組みは?
-
[解決済み] CとC++における「const static」の意味とは?
-
[解決済み] constexprはinlineを意味するのか?