2017-12-14 7 views
-1

私はC++を初めて使い、1つの定義ルールを理解しようとしています。以下のtest.hファイルを複数のC++ファイルに含めると、1つの定義ルール(syspathとタグ)が失敗します。なぜそうでないのであれば?これは1つの定義ルールに違反しないのはなぜですか?

#ifndef TEST_H 
#define TEST_H_ 

#include <string> 
#include <unordered_set> 

namespace X { 

class Test { 
    public: 
    // Default constructor. 
    Test(); 
    ~Test(); 

    const std::string& syspath() const { return syspath_; } 
    const std::unordered_set<std::string> tags() const { return tags_;} 
    private: 
    std::string syspath_; 
    std::unordered_set<std::string> tags_; 
}; 

} // namespace X 

#endif // TEST_H_ 
+2

なぜ*このルールに違反しますか?あなたの特定の懸念事項を指摘しない限り、問題は無意味です。なぜ2 + 2が5でないのか聞いてみるのと同じです。 – AnT

+0

マクロ( '#ifndef'、' #define'と '#endif')はODRを違反しないようにします。 –

+0

@FranciscoGallegoSalido私は彼がそれについて話しているとは思わない。これはコンパイルされますか? –

答えて

2

syspathtagsは、オブジェクトまたは非インライン関数ではありませんので、ODRは、彼らには適用されません。タイプのODRは、それらが間接的に(タイプX::Testの一部として)適用されますが、すべてのコンパイル単位で同一である限り(およびX::Test)、問題ありません。

メモ:ODRの関連部分は2つありますが、コンパイル単位内のテンプレート、型、関数、オブジェクトに適用されるものと、コンパイル単位のオブジェクトおよび非インライン関数に適用されるもの。

1

ODRでは、すべての定義が同じで、各定義が別々の翻訳単位である限り、クラスの複数の定義とインライン関数の定義が可能です。後者の要件は、ヘッダーガードによって満たされます(または、タイプミスがない場合)。

クラス定義は単にデータメンバーを宣言します。これらは変数の定義ではありません。 ODRでは、無制限の宣言が可能です。

クラスのインスタンスが構築されるまで、メンバ変数のインスタンスは存在しません。クラスの各インスタンスには、変数の別のインスタンスが含まれます。

このヘッダーが複数の翻訳単位に含まれている場合、ODRに違反はありません。

関連する問題