c ++中的静态const double

时间:2010-05-05 23:55:47

标签: c++ static

这是使用静态const变量的正确方法吗?在我的顶级课程(形状)

#ifndef SHAPE_H
#define SHAPE_H

class Shape
{
public:

    static const double pi;
private:
    double originX;
    double originY;
};

const double Shape::pi = 3.14159265;

#endif

然后在一个扩展Shape的类中,我使用Shape :: pi。我收到链接器错误。我将const double Shape :: pi = 3.14 ...移动到Shape.cpp文件,然后我的程序编译。为什么会这样?感谢。

7 个答案:

答案 0 :(得分:12)

必须在源文件中定义和初始化静态浮点数据成员。单定义规则禁止在标头中的class {}块之外定义,并且只允许在class {}块内初始化整数数据成员。

这也是不幸的,因为作为一个代数值,拥有即时值可能对优化很有用,而不是从全局变量加载。 (但差异很可能是无关紧要的。)

但是有一个解决方案!

class Shape
{
public:
    static double pi()
        { return 3.14159265; }

private:
    double originX;
    double originY;
};

class{}块中允许使用内联函数定义,包括静态函数定义。

此外,我建议您使用M_PI中的<math.h>,您应该从<cmath>获取。{/ p>

答案 1 :(得分:11)

因为const double Shape::pi = 3.14159265;Shape::pi的定义,而C ++只允许一个符号的单一定义(称为one-definition-rule,你可以在它的首字母缩略词形式ODR中看到)。当定义在头文件中时,每个翻译单元都会获得自己的定义,从而打破该规则。

通过将其移动到源文件中,您只能得到一个定义。

答案 2 :(得分:9)

如果您有办法将C++0x标志添加到编译器中,您可以这样做:

ifndef SHAPE_H
#define SHAPE_H

class Shape
{
public:

    static constexpr double pi = 3.14159265;
private:
    double originX;
    double originY;
};

#endif

C++0x中,您可以将const表达式用于非整数类型的类型。这使您可以声明和定义常量变量。

答案 3 :(得分:3)

这是因为你不能多次定义Shape :: pi。当你在Shape.cpp中包含Shape.h时,它被定义一次,然后在另一个cpp文件中使用Shape.h时再次定义它。当您将程序链接在一起时,链接器将因为多个定义而停止。

答案 4 :(得分:1)

const double Shape::pi = 3.14159265;应该在Shape.cpp文件中。头文件用于声明变量。您只能定义一次变量,因此必须在.cpp中完成。头文件说明了如何使用这些变量和函数,cpp文件说明了该怎么做。

答案 5 :(得分:0)

对于原始数据类型(如int,double但不是char []),您还可以在头文件中的类定义中定义常量,例如:

class Shape
{
public:
    static const double pi = 3.14159265;

private:
    double originX;
    double originY;
};

这将允许更好的编译器优化。

编辑:正如Dennis在下面指出的那样,只允许使用整数类型,而不允许使用double或float数据类型(但是有些编译器会允许它)。

答案 6 :(得分:0)

实现一个函数,该函数返回值的索引(如果存在)。否则,如果没有值,则返回-1。如果列表中存在多个相同的值,则从底部删除第一个值。

public static intfindFromLast (List <Double> l, double value ) {///…}