【转】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 ...
随机推荐
- memcached、cookie、session
Memcached(一个高性能的分布式的内存对象缓存系统) 可用来分担数据库的压力.通过在内存里维护一个统一的巨大的hash表,memcached能存储各种各样的数据,包括图像.视频.文件.以及数据库 ...
- 20165306 Exp6 信息搜集与漏洞扫描
Exp6 信息搜集与漏洞扫描 一.实践内容概述 1.实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 搜索网址目录结构 搜索特定类型的文件 搜索E-Ma ...
- 【python3】 函数 装饰器
第一步 : 了解装饰器 装饰器模式,重点在于装饰,装饰的核心仍是被装饰的对象. 举一个栗子:我今天穿了一件短袖,但是突然一阵风,短袖没办法为我御寒,我想到的办法是将短袖变得更厚更长,但是改造之后,它就 ...
- 数据结构|-用C#实现一个简单的链表
我们知道C#中是没有链表的,我们可以自己实现一个 整个单链表能实现的功能有: 功能 方法 返回值 备注 获取链表长度 GetLength() int 返回值是链表长度 清空链表 Clear() voi ...
- Android之人脸识别
**前言** 人工智能时代快速来临,其中人脸识别是当前比较热门的技术,在国内也越来越多的运用,例如刷脸打卡.刷脸App,身份识别,人脸门禁等等.当前的人脸识别技术分为WEBAPI和SDK调用两种法方式 ...
- spring AOP AspectJ 定义切面实现拦截
总结记录一下AOP常用的应用场景及使用方式,如有错误,请留言. 1. 讲AOP之前,先来总结web项目的几种拦截方式 A: 过滤器 使用过滤器可以过滤URL请求,以及请求和响应的信息,但是过 ...
- Unity --- 设置选择的图片的格式
static void Setting(string assetPath, int maxSize, TextureImporterFormat androidFormat, TextureImpor ...
- JVM垃圾回收(三)- GC算法:基础
GC算法:基础 在介绍GC算法在实际场景中的实现之前,我们先定义一些必要的术语,以及GC算法的基本准则.具体的细节会因收集器的不同而稍有区别,但是基本上来说,所有的收集器会关注以下两个方面: 找出所有 ...
- 【sock_stream和sock_dgram】、 【AF_INET和AF_UNIX】
[sock_stream和sock_dgram] 1.sock_stream 是有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料(如文件)传送. 2.sock_dgram 是无 ...
- maven install报错 Failed to execute goal on project my-manager-mapper: Could not resolve dependencies for project com.my:my-manager-mapper:jar:0.0.1-SNAPSHOT:
报错信息为: [ERROR] Failed to execute goal on project my-manager-mapper: Could not resolve dependencies f ...