ヘッダーファイルで名前空間関数を宣言するにはどうすればよいですか?
namespace MON {
// extern:
t_ret func(const t_param& pValue);
// 'inline':
inline t_ret inline_func(const t_param& pValue) { ... }
} // << MON
ヘッダーにはクラス ヘッダー ファイルのような関数定義のみを含め、実装は cpp ファイルに含める必要がありますか、それともヘッダー ファイルに関数をすぐに実装する必要がありますか?
それは、(潜在的に) インライン化するかエクスポートするかによって異なります。これは多くの場合、依存関係を最小限に抑えることに帰着します。
エクスポートまたはインライン展開を拡張するには:
C++ での依存関係を最小限に抑えるために、extern 関数を使用することがよくあります。これは、クラス メソッドで定義を宣言から分離することと同じです。
ファイル.hpp
namespace MON {
// extern:
t_ret func(const t_param& pValue);
} // << MON
ファイル.cpp
#include "hefty_stuff.hpp"
MON::t_ret MON::func(const t_param& pValue) { ... }
ただし、多くの場合、パフォーマンスのために、またはサイズが重要であり、ヘッダーが多くの場所に含まれていないことがわかっている場合など、場合によっては定義を表示することが重要な場合があります。したがって、inline
バリアントもオプションです。
インライン関数は引き続きエクスポートされる可能性があり、要求に応じてインライン化される可能性があります。ただし、インライン関数のコピーはマージされる可能性があります (具体的には、実装は、すべての定義が等しく、関数のコピーが不要であると自由に想定できます)。
エクスポートされた定義を使用すると、インクルードの依存関係を選択的に制限 (または隔離) できます。つまり#include "hefty_stuff.hpp"
、 の関数を使用するためにヘッダーにある必要はありませんfile.hpp
。
基本的に、いくつかのコマンドを含むテキスト ファイルを解析するアプリケーションを実装しようとしています。そのため、テキスト処理を処理する静的ヘルパー メソッドを実装することを考えています。
まあ、static
ここは避けるべきです。c++ は、1 つの定義規則を使用します。static
不要なコピーが大量に発生するだけです。さらに、匿名名前空間は、c のstatic
関数に対する c++ のアプローチです。
namespace {
t_ret func(const t_param& pValue) { ... }
} // << anon
注: 匿名の名前空間も、不要なコピーになる可能性があります。静的関数の代わりにそれらを使用する理由は、1 つの定義規則から逸脱したい、または逸脱する必要があり、「解決」される可能性のあるスコープでシンボルを宣言したくない場合です。
最後のポイントは、template<>
宣言に関するものです。テンプレートを使用する場合、コンパイラが extern テンプレートをサポートしていない限り、使用されている場所で定義を表示する必要があります。テンプレートの場合、複数の方法で定義の可視性を実現できます。通常、人々は単に定義をその場で宣言するか、ヘッダーの最後または必要に応じて含まれる定義のヘッダーを追加します。inline
テンプレートでは、複数の定義エラーを回避するために関数を宣言する必要はありません。