转自: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. h5 ios键盘卡死页面

    失去焦点以后重新设置页面顶部位置 $('input,textarea').on('blur',function(){ window.scroll(0,0); }); $('select').on('c ...

  2. Vue-admin工作整理(三):路由

    1.router-link和router-view组件 router-link组件实际上是封装了一个a标签(链接标签),里面有一个重要属性:“to”,它的值是一个路径,其路径对应的渲染组件,要在路由列 ...

  3. 虚拟现实外包—动点飞扬软件专门承接VR/AR场景、游戏、项目外包

    VR外包AR外包公司(虚拟现实外包公司)承接虚拟现实项目开发(企业.教育.游戏.企业大数据展示等) 有VR/AR.Unity3D项目.游戏外包业务欢迎 联系我们 QQ:372900288 TEL:13 ...

  4. 【转】LVDS基础、原理、图文讲解

    转自:https://blog.csdn.net/wangdapao12138/article/details/79935821 LVDS是一种低摆幅的差分信号技术,它使得信号能在差分PCB 线对或平 ...

  5. Python字符串 --Python3

    Python语言中,字符串是用两个双引号或者单引号括起来的词汇表或多个字符. 1.Python字符串的两种序号体系 反向递减序号:-- -9 -8 -7 -6 -5 -4 -3 -2 -1 正向递增序 ...

  6. STSdb数据库的实现使用类

    STSdb 3.5是一个开源的key-value存储形式的数据库,它是用微软.net框架C#语言编写的.STSdb 3.5尤其使用于紧急任务或实时系统,如:股市交易,电子通信,实验室数据等,它的主要功 ...

  7. .NET 控件的认识。

    四单元的题目里面,涉及了很多之前没有用过的控件的使用,前12道题都不是很难,所以很快做完了 ,但是后面的因为timer控件找不到,有些操作无法实现,所以就没做,但是也是认真的看了的. 等什么时候把ti ...

  8. 生成器的认识及其思考:VAE, GAN, Flow-based Invertible Model

    生成器对应于认知器的逆过程. 这一切的起源都是当初一个极具启发性的思想:Sleep-wake algorithm——人睡眠时整理记忆做梦,是一个生成的过程,即通过最终的识别结果企图恢复接收到的刺激,当 ...

  9. Linux必备150个命令

       命令                                                        功能说明 线上查询及帮助命令(2个) man 查看命令帮助,命令的词典,更复杂 ...

  10. 微信公众号开发加密解密异常java.security.InvalidKeyException:illegal Key Size

    完美解决: http://blog.csdn.net/u013628152/article/details/46785173