看下面的代码,这个
const static int num1 = 8;
可以编译。但是,const static double num2 = 8.8;
代码给出了错误。它们的修饰符都是const static
,那么为什么int
可以工作,而double
和其他浮点类型会导致错误呢?
struct S {
const static int num1 = 8; // OK
const static double num2 = 8.8; // error
};
我尝试了一些 C++ 的内置类型,发现
int
、short
、long
、char
等整数成员可以在类中用const static
定义并直接初始化,而float
和double
不能。这让我很困惑。
float
数据类型是非整数类型,需要 constexpr
说明符而不是 const
:
class myclass
{
public:
constexpr static double af = 8.8;
const static int ai = 8;
};
原始错误消息可以帮助您调试此问题:
error: 'constexpr' needed for in-class initialization of static data member
'const double myclass::af' of non-integral type
我不知道“为什么浮点类型不能在类中用
const double
初始化,而其他内置类型可以”,但我可以提供其他方法来初始化类中的const static
成员:
不用写
const double a = 8;
,你可以写constexpr double a = 8;
,这两个的区别可以看这里
您可以在类外初始化它,例如:
class myclass {
public:
const static double a;
};
const double myclass::a = 8;
好吧,事实上,
static const double
成员可以在类中初始化——如果你声明它们inline
。如果你想要初始化的值恰好也是一个常量表达式,那么你可以声明它 constexpr
,在这种情况下你不需要声明它 inline
,因为 static constexpr
数据成员会自动内联。
但是,当
static const double
成员不是内联时,则意味着只有一个翻译单元负责提供该成员的 definition,并且该定义负责初始化。因为类定义需要被#include
放入每个想要访问该类成员的翻译单元中,这意味着类内部成员的声明不应该是一个定义(因为这会导致多个定义) 。因此,您必须在类外部的某处提供静态成员的单个定义,并且该单个定义负责初始化它。