最終的にコンパイルされたプログラムでこれら2つのアプローチに違いはありますか、それとも同じであることが保証されていますか?
どちらも同じです。
クラス/構造体本体内で定義されたメンバー関数は暗黙的にinline
.
ただし、最初の例ではinline
、このヘッダーが含まれるすべての翻訳単位で関数を d にすることができます。2 番目の例では、関数を定義する cpp ファイルでのみ関数をインライン化できます。これは、コンパイラが関数呼び出しの時点で関数の定義を確認して、インライン化を試みる必要があるためです。
コメントで Q に回答するには:
としてマークされた関数の定義を cpp ファイルに保持し、inline
このA.cpp
関数を別の cpp ファイルから呼び出そうとするとしますB.cpp
。「未定義の外部シンボル」エラーが発生します。これは、C および C++ では各翻訳単位が個別にコンパイルされ、コンパイル中に にある関数の定義がA.cpp
利用できないためですB.cpp
。
関数が定義されている場所からのみ呼び出されるA.cpp
場合、定義は同じファイルで利用可能であり、コンパイラとリンカーは喜んでコンパイルしてリンクします。
C++03 7.1.2 関数指定子:
パラ 3:
クラス定義内で定義された関数はインライン関数です。インライン指定子は、ブロック スコープの関数宣言には現れません。
優れたコーディング プラクティス/経験の観点から、どちらを選択する必要があり、その理由は何ですか?
クラス定義は、クラスのユーザーへのインターフェースとして機能します。このインターフェースのユーザーは、関数の実装の詳細を確認する必要はありません。彼らが見る必要があるのは、このインターフェイスの使用方法だけです。関数定義(あなたが言及したようにかなり長いもの)をクラス内に配置することにより、ユーザーに不必要な詳細を提供し、実際に見る必要があるものをユーザーが見るのを難しくします.
これを行う最善の方法は次のとおりです。
inline
キーワード &なしでクラス定義で関数を宣言します
- キーワード付きの関数定義を
inline
クラス本体の外に置きます。
よく読んでください:
クラス外で定義されたインライン メンバー関数では、インライン キーワードをクラス本体内の宣言の隣に配置するのが最適ですか?それともクラス本体外の定義の隣に配置するのですか?
私の知る限り、ブーストライブラリのほとんどはヘッダーのみです-なぜそれを選択したのですか?
Boost ライブラリのほとんどはテンプレート ライブラリであり、テンプレート ベースのライブラリの場合、コンパイラは使用時に定義を確認する必要があるため、テンプレート関数をインラインにする必要があります。
よく読んでください:
テンプレートをヘッダー ファイルにしか実装できないのはなぜですか?