我有以下声明:
class Rm
{
public:
//defined message types
static const int HELLO;
}
我在cpp文件中的:
const int Rm::HELLO = 1;
但是当我尝试在另一个类的方法中使用它时:
int
Rn::ProcessMessages()
{
messagesIter iter = messages.begin();
while(iter != messages.end())
{
switch(iter->first)
{
case Rm::HELLO:
myID = iter->second;
break;
}
}
}
我明白了: 错误:'Rm :: HELLO'不能出现在常量表达式Rm :: HELLO:
我做错了什么?
答案 0 :(得分:4)
成员变量是常量,但它不是编译时常量。为此,您需要在C ++ 11中引入的constexpr
关键字:
class Rm
{
public:
//defined message types
static constexpr int HELLO = 1;
};
如果您没有支持C ++ 11的编译器,则可以改为使用枚举:
class Rm
{
public:
//defined message types
enum
{
HELLO = 1
};
};
答案 1 :(得分:3)
为了在HELLO
中使用switch
值,此时编译器需要知道它。基本上,对于整数类型的成员常量,意味着在声明中提供初始化值。因此,而不是
static const int HELLO;
DO
static const int HELLO = -1;
尽管初始化程序仍然只是一个纯声明。如果您获取此地址,则需要单独的定义。只是不要拿地址。
以上适用于整数类型,但即使是double
成员常量也不能以这种方式定义,原因不明。另一种方法是使用C ++ 11 constexpr
,但此时限制了代码的可移植性。 C ++ 03非整数类型常量的替代方法包括
使用命名空间级别常量,而不是成员。
使用产生(引用)值的函数。
在类模板中定义常量,从专业化派生您的类。
最后需要注意的是,在C ++中,请为宏保留所有大写名称,例如HELLO
。这样,您可以减少不需要的名称冲突和文本替换,并且代码也变得更容易。即,在C ++中使用名称hello
,或Hello
,或...
所有大写都用在某些语言中,特别是Java和Python,作为常量名称的约定,主要是因为原始C常量必须表示为宏。
在这些语言中,除了作为眼睛之外,所有大写都没有任何不良影响,但C ++确实有一个预处理器。