请考虑以下迷你示例
// CFoo.hpp
class CFoo{
private:
static const double VPI = 0.5;
public:
double getVpi();
};
// CFoo.cpp
#include "CFoo.hpp"
double CFoo::getVpi(){
double x = -VPI;
return x;
}
// main.cpp
#include "CFoo.hpp"
int main(){
CFoo aFoo();
return 0;
}
使用gcc版本4.5.1填充程序会产生错误CFoo.cpp: undefined reference to CFoo::VPI
。如果
double x = -1 * VPI;
你知道这个错误的原因吗?
答案 0 :(得分:5)
您的代码存在多个问题。首先,这不是有效的C ++ 03:
class CFoo{
private:
static const double VPI = 0.5;
// ...
};
当且仅当该初始值设定项为const
整数或const
枚举类型时,静态数据成员的声明才能指定常量初始值设定项。 0.5
不是这些,因此您的代码不是有效的C ++。 9.4.2静态数据成员涵盖了这一点:
2 /在其类定义中声明静态数据成员是 不是定义[...]静态数据成员的定义应 出现在包含成员类定义的命名空间范围内。 [...]
4 /如果静态数据成员是const integral或const枚举 type,它在类定义中的声明可以指定一个 常量初始化器,它应是一个整数常量表达式 (5.19)。
要初始化VPI
,您必须在CPP文件中执行此操作:
class CFoo{
private:
static const double VPI;
};
const double CFoo::VPI = 0.5;
另一个无关的问题是:
int main(){
CFoo aFoo(); // NOT OK
return 0;
表达式CFoo aFoo();
不符合您的想法。您认为它声明了aFoo
类型的对象CFoo
,并使用CFoo
的默认构造函数对其进行初始化。但它实际上做的是声明一个名为aFoo
的函数,不带参数,按值返回CFoo
。这被称为most vexing parse。为了做你想做的事,简单地省略括号:
CFoo aFoo;