複数のcppファイルに定義を含むhファイルをインクルードする[重複]

Aug 21 2020

私の問題は、関数定義を含むヘッダーファイル(カスタムユニットテストフレームワーク)があることです。例:
unit_test.h:

#pragma once
...    
void Assert(bool b, const string& hint = {})
{
    AssertEqual(b, true, hint);
}
...

unit_test.hは別のディレクトリにありますC:/Dev/include)を含めるだけでこの関数を使用することが多いため、一部の関数をヘッダーで正しく定義しておくと便利です。
しかし、複数のcppファイルがこの機能を使用するプロジェクトを扱っている場合、期待どおりに複数の定義エラーが発生します。
単純なプロジェクトは次のようになります:

main.cpp:

#include "unit_test.h"

void foo();

int main()
{
    Assert(1);
    foo();
    return 0;
}

foo.cpp:

#include "unit_test.h"

void foo()
{
    Assert(2);
}

それで、関数定義をヘッダーファイルに保持し、複数定義エラーを取得せずにプロジェクトで使用する正しい方法があるかどうかを知りたいですか?
または、関数定義をソースに移動して毎回個別にコンパイルするか、unit_testを静的ライブラリにコンパイルする方がよいでしょうか?

回答

1 KrzysztofMochocki Aug 21 2020 at 17:43

これを実現する最も簡単な方法はinline、関数定義にキーワードを追加することですが、これは最善の解決策ではありません。

最良のオプションは、定義をソースファイルに移動することですが、それだけがテンプレートではありません。

1 Nikola Aug 21 2020 at 18:00

インラインで匿名の名前空間を使用します:

namespace {
    inline void Assert(bool b, const string& hint = {})
    {
        AssertEqual(b, true, hint);
    }
}
Imran Aug 21 2020 at 18:12

このエラーは、ファイルを含めるたびに関数が再度定義されるためです。解決策は、宣言のみを含むヘッダーファイルunit_test.hを作成し、定義用のソースファイルunit_test.cppを作成することです。これで、エラーが発生しないヘッダーファイルをインクルードできます。次のようにヘッダーに#ifndefを追加することを忘れないでください

unit_test.h

#ifndef UNIT_TEST_H_
#define UNIT_TEST_H_
// Declare you function
// and end with:
#endif