这是使用静态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文件,然后我的程序编译。为什么会这样?感谢。
答案 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 ) {///…}