为什么否定静态成员变量会产生链接器错误

Why does negating a static member variable produce a linker error?

本文关键字:链接 错误 静态成员 变量 为什么      更新时间:2023-10-16

请考虑以下mini示例

// 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。错误剂量不发生

如果发生
  • vpi不被否定
  • 否定写为double x = -1 * VPI;
  • 类CFO的声明和定义发生在同一文件中

您知道此错误的原因吗?

您的代码有多个问题。主要是,这不是有效的C 03:

class CFoo{
private:
    static const double VPI = 0.5;    
// ...
};

静态数据成员的声明可以在且仅当该初始化器为const积分或const枚举类型时指定常数初始化程序。0.5都不是这些,因此您的代码无效C 。 9.4.2静态数据成员涵盖以下内容:

2/静态数据成员在其类定义中的声明是 不是定义[...]静态数据成员的定义 出现在封闭会员类定义的名称空间范围中。 [...]

4/如果静态数据成员是const积分或句子枚举 类型,其在类定义中的声明可以指定 恒定量子器,这将是整体恒定表达式 (5.19)。

为了初始化VPI,您必须在CPP文件中这样做:

标题:

class CFoo{
private:
    static const double VPI;    
};

CPP:

const double CFoo::VPI = 0.5;

另一个无关的问题在这里:

int main(){
    CFoo aFoo(); // NOT OK
    return 0;

表达式CFoo aFoo();不做您认为的事情。您认为它声明了CFoo类型的对象aFoo,并使用CFoo的默认构造函数初始化它。但是,实际上要做的是声明一个名为 aFoo的函数,没有参数,返回 CFoo逐个值。这被称为最烦人的解析。为了做您想做的事,简单省略了括号:

CFoo aFoo;