C++ c+中的静态常数双精度+;

C++ c+中的静态常数双精度+;,c++,static,C++,Static,这是使用静态常量变量的正确方法吗?在我的顶级班级(Shape) 后来在一个扩展Shape的类中,我使用Shape::pi。我得到一个链接器错误。我移动了常数双形::pi=3.14。。。到Shape.cpp文件,然后我的程序编译。为什么会这样?谢谢。因为const-double-Shape::pi=3.14159265是“代码>形状::Pi”和“C++”只允许一个符号的单一定义(称为“您可以从它的缩写形式ODR中看到”)。当定义在头文件中时,每个翻译单元都会得到自己的定义,这违反了该规则 通过将其

这是使用静态常量变量的正确方法吗?在我的顶级班级(Shape)


后来在一个扩展Shape的类中,我使用Shape::pi。我得到一个链接器错误。我移动了常数双形::pi=3.14。。。到Shape.cpp文件,然后我的程序编译。为什么会这样?谢谢。

因为
const-double-Shape::pi=3.14159265是“代码>形状::Pi”和“C++”只允许一个符号的单一定义(称为“您可以从它的缩写形式ODR中看到”)。当定义在头文件中时,每个翻译单元都会得到自己的定义,这违反了该规则


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

之所以会出现这种情况,是因为您不能多次定义Shape::pi。在Shape.cpp中包含Shape.h时定义一次,在另一个cpp文件中使用Shape.h时定义一次。当您将程序链接到一起时,链接器会因为多个定义而呕吐。

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

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

这也是不幸的,因为作为一个代数值,手头有立即数对于优化来说可能很好,而不是从全局变量加载。(不过,这种差异可能无关紧要。)

不过,有一个解决办法

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

private:
    double originX;
    double originY;
};
内联函数定义,包括静态函数定义,允许在
class{}
块中使用

此外,我建议使用
中的
M_PI
,对于基本数据类型(如int、double而非char[]),您还可以在头文件中的类定义中定义常量,例如:

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

private:
    double originX;
    double originY;
};
这将允许更好的编译器优化


编辑:正如Dennis在下面指出的,这只允许用于整型数据类型,而不允许用于双精度或浮点数据类型(但是有些编译器会允许)。

如果您有办法将
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
中,可以对整型以外的类型使用常量表达式。这使您能够就地声明和定义常量变量。

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

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

此外:模板具有不同的链接,因此您可以使用模板进行定义visible@Justin:我不认为
template
在这里给你带来任何东西,除了额外的复杂性。一个模板可能会使事情复杂化,但它确实可能给你带来一个例外,一个定义规则的例外“类模板的静态数据成员”(除其他ODR异常之外)。参见C++标准的3.2/5和145.1.3。@米迦勒:但是标识模板数据成员在使用中需要模板参数列表,它不比函数调用乏味(而且稍微不太清楚)。+ 1用于解决方案(我明确声明为
inline
)您只能对整型和枚举类型执行此操作。浮点类型是不允许的。@Dennis:Oops!您说得对!我被编译器愚弄了(gcc和icc允许在类内初始化静态const double)…我也有同样的问题。问题是,如果这是一个库,我希望我的用户在.h文件中看到Shape::pi的值,而不是cpp内容(即其他函数定义)。我该怎么办?您好,根据c++11中引入的constexpr,因此,编译器标志不应该是c++11、14、17或20,尤其是“c++0x”吗“?我的回答已经有8年了。当时没有c++17。不过你可以自由编辑答案。
public static intfindFromLast (List <Double> l, double value ) {///…}