我正在阅读关于gtest的介绍并发现这部分令人困惑:
编译器抱怨某些静态的“未定义引用” const成员变量,但我确实在类体中定义它们。 怎么了?
如果您的班级有静态数据成员:
// foo.h class Foo { ... static const int kBar = 100; };
您还需要在foo.cc中的类主体之外定义它:
const int Foo::kBar; // No initializer here.
否则您的代码无效的C ++ ,并且可能会意外中断 方法。特别是在Google Test比较断言中使用它 (EXPECT_EQ等)将生成“未定义的引用”链接器错误。
有人可以解释为什么在类中定义静态const而不在类体外定义它是非法的C ++?
答案 0 :(得分:5)
首先,在类体内部不是定义,它是一个声明。声明指定常量的类型和值,该定义保留存储空间。您可能不需要存储空间,例如,如果您仅将该值用作编译时常量。在这种情况下,您的代码是完全合法的C ++。但是如果你做的事情就像通过引用传递常量,或者使指针指向常量那么你也需要存储。在这些情况下,您会收到“未定义的引用”错误。
答案 1 :(得分:3)
标准基本上表明即使你可以在标题中给出一个值,如果静态变量被“使用”,你必须仍然在源文件中定义它。
在此上下文中,“used”通常被理解为表示程序的某些部分需要实际内存和/或变量的地址。
谷歌测试代码很可能在某个时刻获取变量的地址(或以其他一些等效的方式使用它)。
答案 2 :(得分:2)
粗略地说:在类定义中,static const int kBar = 100;
告诉编译器“Foo将有一个kBar常量(我保证永远为100)”。但是,编译器不知道该变量的位置。在foo.cc文件中,const int Foo::kBar;
告诉编译器“好吧,在这个地方制作kBar”。否则,链接器会寻找kBar,但无法在任何地方找到它。