【转】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 ...
随机推荐
- mybatis逆向工程失败
[ERROR] Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.6:generate ( ...
- You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group t1,customer t2
### SQL: select t1.gid,t1.gname,t1.gvalue,t1.gtype, t1.gaddress,t1.gmembers, t1.gcode,t1.gphone, t2. ...
- Table组件设置文字超出宽度显示省略号,鼠标悬停以悬浮框显示
一.设置文字超出宽度显示省略号 注意点: 1. 需要指定column的width属性,否则列头跟内容可能不对齐.需要留一列不设置宽度以适应弹性布局. 2. 列宽度width必须大于ellipsis的 ...
- Linux——高效玩转命令行
[0]统计文件or压缩文件的行数 zcat file.gz | sed -n '$=' #迅速.直接打印出多少行.-n 取消默认的输出,使用安静(silent)模式 '$=' 不知道是什么 ...
- php 发邮件的2种方式(使用stmp类、使用socket协议)
方式1:使用stmp类发送邮件 代码: stmp.php <?php header("Content-Type: text/html; charset=utf-8"); cl ...
- canvas 模拟时钟
<meta charset="utf-8"> <canvas width="1000" height="1000" id= ...
- js斐波那契数列
斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...... 这个数列从第3项开始,每一项都等于前两项之和. 1.递归算法: function ...
- 【设计模式】工厂模式(Factory Pattern)
[前言] 很多时候我们编写了好几个接口的实现类,这些实现类分别有不同特性,用在不同的情景下.而我们对于这些实现类,也往往不会对外暴露内部增加的方法,只希望外部调用接口的方法,在这种情况下,我们没必要让 ...
- 接口测试工具Jmeter
一.安装Jmeter 1.安装JDK ①下载jdk,到官网下载jdk,地址:http://jmeter.apache.org/download_jmeter.cgi ② 安装jdk(Oracle官网下 ...
- Redis(三)-数据类型
1.五种数据类型:字符串类型.字符串列表.有序字符串集合.哈希.字符串集合 2.字符串类型常用操作 (1)赋值 $ set key value (2)取值 $ get key (3)删除 $ del ...