【转】forbids in-class initialization of non-const static member不能在类内初始化非const static成员
转自: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成员的更多相关文章
- c++类与初始化,const
--c++类与初始化,const --------------------------------2014/09/04 1. 类的定义(头文件.声明文件)看成类的外部接口,一般写成.h头文件. 2. ...
- 为什么const对象只能调用const成员函数,而不能调用非const成员函数?
在c++中,我们可以用const来定义一个const对象,const对象是不可以调用类中的非const成员函数,这是为什么呢?下面是我总结的一些原理. 假设有一个类,名字为test代码如下: clas ...
- .static 和const分别怎么用,类里面static和const可以同时修饰成员函数吗。
static的作用: 对变量: 1.局部变量: 在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量. 1)内存中的位置:静态存储区 2)初始化:局部的静态变量只能被初始化一次, ...
- 非const引用参数传入不同类型编译不过的理解(拒绝将临时对象绑定为非const的引用的形参是有道理的)
int f (int & I) { cout<<I<<std::endl; } void main() { long L; f(L); // 编译不过 f((int)L ...
- Delphi函数参数传递 默认参数(传值)、var(穿址)、out(输出)、const(常数)四类
Delphi的参数可以分为:默认参数(传值).var(传址).out(输出).const(常数)四类 可以对比C/C++的相关知识,类比学习. 1.默认参数是传值,不会被改变,例子 function ...
- 临时变量不能作为非const类型引用形参的实参
摘要: 非const 引用形参只能与完全同类型的非const对象关联. 具体含义为:(1)不能用const类型的对象传递给非const引用形参: ( ...
- C++-const_cast只能用于指针和引用,对象的const到非const可以用static_cast
Static_cast可以对对象也可以对指针也可以对引用,但是const_cast只可以对指针和引用使用,后者不可以对对象用,如果你要把一个const值转化为非const值只能用隐式执行或通过使用st ...
- 类内const static(static const)成员变量初始化问题
在查找const相关资料的过程中,又遇到了另外一个问题,就是C++类中const static(或者static const)成员变量应当如何初始化的问题. 查阅了许多资料,发现VC环境下,只允许co ...
- C++类静态成员变量和const常量的初始化方法
C++类静态成员变量和const常量在定义类的时候就必须初始化,否则都会编译出错. 而具初始化方法为: C++类静态成员变量初始化方法 #include <iostream> #inclu ...
随机推荐
- h5 ios键盘卡死页面
失去焦点以后重新设置页面顶部位置 $('input,textarea').on('blur',function(){ window.scroll(0,0); }); $('select').on('c ...
- Vue-admin工作整理(三):路由
1.router-link和router-view组件 router-link组件实际上是封装了一个a标签(链接标签),里面有一个重要属性:“to”,它的值是一个路径,其路径对应的渲染组件,要在路由列 ...
- 虚拟现实外包—动点飞扬软件专门承接VR/AR场景、游戏、项目外包
VR外包AR外包公司(虚拟现实外包公司)承接虚拟现实项目开发(企业.教育.游戏.企业大数据展示等) 有VR/AR.Unity3D项目.游戏外包业务欢迎 联系我们 QQ:372900288 TEL:13 ...
- 【转】LVDS基础、原理、图文讲解
转自:https://blog.csdn.net/wangdapao12138/article/details/79935821 LVDS是一种低摆幅的差分信号技术,它使得信号能在差分PCB 线对或平 ...
- Python字符串 --Python3
Python语言中,字符串是用两个双引号或者单引号括起来的词汇表或多个字符. 1.Python字符串的两种序号体系 反向递减序号:-- -9 -8 -7 -6 -5 -4 -3 -2 -1 正向递增序 ...
- STSdb数据库的实现使用类
STSdb 3.5是一个开源的key-value存储形式的数据库,它是用微软.net框架C#语言编写的.STSdb 3.5尤其使用于紧急任务或实时系统,如:股市交易,电子通信,实验室数据等,它的主要功 ...
- .NET 控件的认识。
四单元的题目里面,涉及了很多之前没有用过的控件的使用,前12道题都不是很难,所以很快做完了 ,但是后面的因为timer控件找不到,有些操作无法实现,所以就没做,但是也是认真的看了的. 等什么时候把ti ...
- 生成器的认识及其思考:VAE, GAN, Flow-based Invertible Model
生成器对应于认知器的逆过程. 这一切的起源都是当初一个极具启发性的思想:Sleep-wake algorithm——人睡眠时整理记忆做梦,是一个生成的过程,即通过最终的识别结果企图恢复接收到的刺激,当 ...
- Linux必备150个命令
命令 功能说明 线上查询及帮助命令(2个) man 查看命令帮助,命令的词典,更复杂 ...
- 微信公众号开发加密解密异常java.security.InvalidKeyException:illegal Key Size
完美解决: http://blog.csdn.net/u013628152/article/details/46785173