クライアントが使いやすいように、作業中のライブラリをヘッダーのみのライブラリとしてパッケージ化したいと思います。(これは小さく、別の変換ユニットに配置する理由は実際にはありません)ただし、これはC ++の単一定義規則に違反するため、コードをヘッダーに単純に配置することはできません。(ライブラリヘッダーがクライアントプロジェクトの複数の翻訳ユニットに含まれていると仮定します)
ライブラリを変更してヘッダーのみにする方法はありますか?
クライアントが使いやすいように、作業中のライブラリをヘッダーのみのライブラリとしてパッケージ化したいと思います。(これは小さく、別の変換ユニットに配置する理由は実際にはありません)ただし、これはC ++の単一定義規則に違反するため、コードをヘッダーに単純に配置することはできません。(ライブラリヘッダーがクライアントプロジェクトの複数の翻訳ユニットに含まれていると仮定します)
ライブラリを変更してヘッダーのみにする方法はありますか?
inline
次のキーワードを使用できます。
// header.hpp (included into multiple translation units)
void foo_bad() {} // multiple definitions, one in every translation unit :(
inline void foo_good() {} // ok :)
inline
リンカが1つの定義を選択し、残りを破棄できるようにします。
(したがって、これらの定義が実際に一致しない場合は、未定義の動作が大量に発生します...!)
余談ですが、クラスタイプ内で定義されたメンバー関数は、暗黙的にマークされていinline
ます。
struct myclass
{
void i_am_inline_implicitly()
{
// because my definition is here
}
void but_i_am_not();
void neither_am_i();
};
inline void myclass::but_i_am_not()
{
// but that doesn't mean my definition cannot be explicitly inline
}
void myclass::neither_am_i()
{
// but in this case, no inline for me :(
}
Lizが提案するようにヘッダーガードを使用し、関数メソッドの前に「インライン」を置くことを忘れないでください。
すなわち
#ifndef MY_HEADER_H_
#define MY_HEADER_H_
inline RetType FunctionName( ParamType1 param1, ParamType2 param2 )
{
// Function body
return retType;
}
#endif
また、ヘッダーのみのライブラリコードでグローバル変数や静的変数を使用することは避ける必要があると思います。
1か所でコンパイルされる部分にはヘッダーガードを使用します。