为什么这不违反一个定义规则?

时间:2017-12-14 00:20:07

标签: c++ linkage

我是c ++的新手,并试图理解单一定义规则。在多个c ++文件中包含下面的test.h文件会消除一个定义规则(syspath和tags)。如果不是为什么不呢?

 #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 个答案:

答案 0 :(得分:2)

syspathtags不是对象或非内联函数,因此ODR不适用于它们。类型的ODR间接地适用于它们(因为它们属于X::Test类型的一部分),但只要它们(和X::Test)在每个编译单元中都相同,它们就是&#39;好的。

作为wikipedia page注释,ODR有两个相关但不同的部分 - 一个适用于编译单元内的模板,类型,函数和对象,另一个适用于对象和非内联函数跨编译单位。

答案 1 :(得分:1)

ODR允许类的多个定义以及内联函数的定义,只要所有定义相同,并且每个定义都在单独的转换单元中。后者的要求由标题保护人员满足(或者如果没有标题错误的话)。

类定义仅声明数据成员。这些不是变量定义。 ODR允许无限制声明。

在构造类的实例之前,不存在成员变量的实例,并且该类的每个实例都包含该变量的单独实例。

如果此标头包含在多个翻译单元中,则不会违反ODR。