谁能解释为什么以下代码无法编译?至少在g ++ 4.2.4上.
更有趣的是,为什么它会在我将MEMBER转换为int时进行编译?
#includeclass Foo { public: static const int MEMBER = 1; }; int main(){ vector v; v.push_back( Foo::MEMBER ); // undefined reference to `Foo::MEMBER' v.push_back( (int) Foo::MEMBER ); // OK return 0; }
Drew Hall.. 193
您需要在某处(在类定义之后)实际定义静态成员.试试这个:
class Foo { /* ... */ }; const int Foo::MEMBER; int main() { /* ... */ }
那应该摆脱未定义的引用.
您需要在某处(在类定义之后)实际定义静态成员.试试这个:
class Foo { /* ... */ }; const int Foo::MEMBER; int main() { /* ... */ }
那应该摆脱未定义的引用.
问题来自于新C++功能的有趣冲突以及您正在尝试做的事情.首先,我们来看看push_back
签名:
void push_back(const T&)
它期望引用类型的对象T
.在旧的初始化系统下,存在这样的成员.例如,以下代码编译得很好:
#includeclass Foo { public: static const int MEMBER; }; const int Foo::MEMBER = 1; int main(){ std::vector v; v.push_back( Foo::MEMBER ); // undefined reference to `Foo::MEMBER' v.push_back( (int) Foo::MEMBER ); // OK return 0; }
这是因为某个实际对象的某个值存储在其中.但是,如果切换到指定静态const成员的新方法(如上所述),Foo::MEMBER
则不再是对象.这是一个常数,有点类似于:
#define MEMBER 1
但是没有预处理器宏(并且具有类型安全性)的头痛.这意味着期望参考的向量不能得到一个.
如果以某种方式需要定义,则C++标准需要静态const成员的定义.
该定义是必需的,例如,如果使用它的地址. push_back
通过const引用获取其参数,因此编译器需要您的成员的地址,您需要在命名空间中定义它.
当您显式地转换常量时,您正在创建一个临时的,这是临时的,它绑定到引用(在标准中的特殊规则下).
这是一个非常有趣的案例,我实际上认为值得提出一个问题,以便将std更改为对您的常量成员具有相同的行为!
虽然,以一种奇怪的方式,这可以被视为合法使用一元'+'运算符.基本上,结果unary +
是rvalue,因此rvalues绑定到const引用的规则适用,我们不使用静态const成员的地址:
v.push_back( +Foo::MEMBER );
Aaa.h
class Aaa { protected: static Aaa *defaultAaa; };
Aaa.cpp
// You must define an actual variable in your program for the static members of the classes static Aaa *Aaa::defaultAaa;