49

クライアントが使いやすいように、作業中のライブラリをヘッダーのみのライブラリとしてパッケージ化したいと思います。(これは小さく、別の変換ユニットに配置する理由は実際にはありません)ただし、これはC ++の単一定義規則に違反するため、コードをヘッダーに単純に配置することはできません。(ライブラリヘッダーがクライアントプロジェクトの複数の翻訳ユニットに含まれていると仮定します)

ライブラリを変更してヘッダーのみにする方法はありますか?

4

4 に答える 4

77

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 :(
}
于 2010-02-08T22:41:31.370 に答える
10

Lizが提案するようにヘッダーガードを使用し、関数メソッドの前に「インライン」を置くことを忘れないでください。

すなわち

#ifndef MY_HEADER_H_
#define MY_HEADER_H_

inline RetType FunctionName( ParamType1 param1, ParamType2 param2 )
{
    // Function body
    return retType;
}

#endif
于 2010-02-08T22:41:48.217 に答える
5

また、ヘッダーのみのライブラリコードでグローバル変数や静的変数を使用することは避ける必要があると思います。

于 2010-02-08T22:41:59.673 に答える
-2

1か所でコンパイルされる部分にはヘッダーガードを使用します。

于 2010-02-08T22:40:42.587 に答える