转自: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;
};

编译后:



我是不大记得书上的具体说明的位置了,百度了一下,恰好stackoverflow上有这样一个帖子,我觉得回答的很专业,翻译一下,记录下来,为了保持原意,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这样的变量被允许使用类内初始化,但是获取这样的变量的地址是不被允许的。一个变量只有拥有类外定义的情况下,才能被获得地址。

【转】forbids in-class initialization of non-const static member不能在类内初始化非const static成员的更多相关文章

  1. c++类与初始化,const

    --c++类与初始化,const --------------------------------2014/09/04 1. 类的定义(头文件.声明文件)看成类的外部接口,一般写成.h头文件. 2. ...

  2. 为什么const对象只能调用const成员函数,而不能调用非const成员函数?

    在c++中,我们可以用const来定义一个const对象,const对象是不可以调用类中的非const成员函数,这是为什么呢?下面是我总结的一些原理. 假设有一个类,名字为test代码如下: clas ...

  3. .static 和const分别怎么用,类里面static和const可以同时修饰成员函数吗。

    static的作用: 对变量: 1.局部变量: 在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量. 1)内存中的位置:静态存储区 2)初始化:局部的静态变量只能被初始化一次, ...

  4. 非const引用参数传入不同类型编译不过的理解(拒绝将临时对象绑定为非const的引用的形参是有道理的)

    int f (int & I) { cout<<I<<std::endl; } void main() { long L; f(L); // 编译不过 f((int)L ...

  5. Delphi函数参数传递 默认参数(传值)、var(穿址)、out(输出)、const(常数)四类

    Delphi的参数可以分为:默认参数(传值).var(传址).out(输出).const(常数)四类 可以对比C/C++的相关知识,类比学习. 1.默认参数是传值,不会被改变,例子 function ...

  6. 临时变量不能作为非const类型引用形参的实参

    摘要:     非const 引用形参只能与完全同类型的非const对象关联.      具体含义为:(1)不能用const类型的对象传递给非const引用形参:                  ( ...

  7. C++-const_cast只能用于指针和引用,对象的const到非const可以用static_cast

    Static_cast可以对对象也可以对指针也可以对引用,但是const_cast只可以对指针和引用使用,后者不可以对对象用,如果你要把一个const值转化为非const值只能用隐式执行或通过使用st ...

  8. 类内const static(static const)成员变量初始化问题

    在查找const相关资料的过程中,又遇到了另外一个问题,就是C++类中const static(或者static const)成员变量应当如何初始化的问题. 查阅了许多资料,发现VC环境下,只允许co ...

  9. C++类静态成员变量和const常量的初始化方法

    C++类静态成员变量和const常量在定义类的时候就必须初始化,否则都会编译出错. 而具初始化方法为: C++类静态成员变量初始化方法 #include <iostream> #inclu ...

随机推荐

  1. mongodb在ubuntu下无法打开的问题

    通过查询大概知道了是非正常关闭,mongod.lock的事,ubuntu的mongod.lock在/var/lib/mongodb中,删除之后即可重新打开.

  2. intelliJ idea常用快捷键 mac版

    目录 coding project coding Command + P 显示方法参数信息 Command + N 自动生成getter.setter.hashCode.equals.toString ...

  3. php日志

    // 全局通用日志工具 function setlog($param = [],$result = [],$name='',$filename = 'm.log',$path = '/tmp/bear ...

  4. Shopping List

    剃须啫喱 吉列 70g $22.00 鲁阳家居专营店 剃须水套装 阿帕奇+酷曼 230g+230g $16.80(限时活动) 鲁阳家居专营店 鸡胸肉 撸铁党 100gx9+100g $49.9(限时活 ...

  5. git与github工具使用

    这篇文章主要的目标是用较少的时间学习Git和GitHub的基本使用.在足够一般使用的前提下,尽量减少命令.如果需要其他命令,到时候再去其他地方了解就行了. 总概:所有命令前都要加 git,如下的ini ...

  6. python 学习笔记 2 ----> dive into python 3

    Python Shell idle的使用 >>> >>>help() ----> help> 可以在help这个工具中查找Python内置函数的文档等等 ...

  7. VUE 创建element项目

    前提:电脑安装git node.js 一.右键Git Bash Here 二.$ vue init webpack element //新建一个element项目,element是文件夹名字 $ cd ...

  8. C#数组--(Array类的属性和方法)

    Array 类是 C# 中所有数组的基类,它是在 System 命名空间中定义.Array 类提供了各种用于数组的属性和方法,可看作扩充了功能的数组(但不等同数组),可以使用Array类的属性来对数组 ...

  9. Django框架简介-路由系统

    2.2 路由系统 Django 1.11版本 URLConf官方文档 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表. 你就是 ...

  10. 基于服务器AAA实验

    ---恢复内容开始--- 一.实验拓扑 二.实验地址分配  设备  端口  ip  掩码  AAAA  g0/0 and se0/3/0  192.168.1.1 and 192.168.4.1  2 ...