欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【转】forbids in-class initialization of non-const static member不能在类内初始化非const static成员

程序员文章站 2023-04-05 19:37:13
转自: "forbids in class initialization of non const static member不能在类内初始化非const static成员" 今天写程序,出现一个新错误,好吧,感觉每次编程都能遇到新问题,我期待久病成医的那一天,哈哈。事故代码如下: 编译后: 我是不 ......

转自:
今天写程序,出现一个新错误,好吧,感觉每次编程都能遇到新问题,我期待久病成医的那一天,哈哈。事故代码如下:

class employee  
{  
public:  
    employee() {myid = id++;};  
    employee(const std::string &n) {myid = id++;name = n;};  
    int get_id() {return myid;}  
    const std::string get_name() {return name;};  
private:  
    std::string name;  
    static int id;  
    int myid;  
};  

编译后:
【转】forbids in-class initialization of non-const static member不能在类内初始化非const static成员
我是不大记得书上的具体说明的位置了,百度了一下,恰好*上有这样一个帖子,我觉得回答的很专业,翻译一下,记录下来,为了保持原意,static,constant,integral就不翻译了,相信大家都明白:


问:为什么我不能在类内初始化static成员?

采纳回答:c++标准只允许static constant intergral或者枚举类型的数据在类内进行初始化。
引用:c++03 9.4.2 static data members

§4 if a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). in that case, the member can appear in integral constant expressions. the member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

如果一个静态数据成员是constant integral或者const numeration类型,那么它类内的声明中如果包含定义部分,定义部分应该是一个integral constant表达式。在这个情况下,成员可以出现在一个integral constant表达式中。如果这个成员在程序中被使用,应该明确其命名空间的域范围,且不能包含初始化程序

什么是integral 类型?

bool char wchar_t 包含被signed或者unsigned修饰的情况。统称integral类型(这句话我理解为c++里面的基本类型,和string、数组区分),integral类型的同义词是integer类型。

脚注:
因此,enumerations不是integral,但是,enumerations可以被转化为int,unsigned int,long,unsigned long。
工作区(原文就是这么写,大概就是代码例程的区域吧):
你可以使用enum的小戏法初始化类内数组:

class a   
{  
    static const int a = 3;  
    enum { arrsize = 2 };  
    static const int c[arrsize] = { 1, 2 };  
};  

为什么标准不允许这一行为?
bjarne这样解释:

一个类会被特别定义在一个头文件中,并且头文件会被包含在许多转换单元里。但是,为了防止链接规则过于复杂,c++需要每一个对象有特定的定义。如果c++允许存储在内存中的对象进行类内定义,那么这一规则将会被打破。

why are only static
const integral types & enums allowed in-class initialization?
为什么只有static const integral类型以及enums被允许类内初始化呢?
这个答案就在bjarne的那段话中。“c++需要每一个对象有特定的定义。如果c++允许存储在内存中的对象进行类内定义,那么这一规则将会被打破。”

注意只有static const integers 会被看作编译时的常量。编译器了解这样的integer变在任何情况下都不会改变,因此编译器才可以对其做出特有的优化与改进,编译器会简单的将其内联化这样的变量,因而不再使其保存在内存中。因为保存在内存中的需求被移除了,使得他们成了bjane所说规则的例外。

值得注意的是,即使static const integral这样的变量被允许使用类内初始化,但是获取这样的变量的地址是不被允许的。一个变量只有拥有类外定义的情况下,才能被获得地址。