C++11类内static成员变量声明与定义
众所周知,将一个类内的某个成员变量声明为static型,可以使得该类实例化得到的对象实现对象间数据共享。
在C++中,通常将一个类的声明写在头文件中,将这个类的具体定义(实现)写在cpp源文件中。
因此,就引出了static成员变量的声明与定义问题:
1. 如果一个类内成员变量是static的,且需要将之设定为常量(const),那么这个变量声明与初始化均可写在头文件内。
举个例子:
// Scanner.hpp
class Scanner {
public:
const static int MAX_SIZE = 0xFFFF;
...
};
这里直接将MAX_SIZE声明与定义写在了头文件。这很好理解,编译器在为这个类分配内存空间的时候,已经知道了这个类内变量无需为每个对象“拷贝”一份(因为它是static的),并且又知道了它在程序运行过程中的值保持不变(因为它是const的),那么就可以直接将其处理。因此头文件内的类声明实现信息已经足够,从而这样的写法是合理的。
需要注意的是,不能在头文件内声明const static成员变量,而在具体源cpp文件内实现其初始化。因为这样编译器需要根据具体的实现文件来确定该成员变量的初始值,若实际应用中没有相应的实现文件(源cpp文件)来对这个成员变量实现初始化,则编译器无法明确意图,从而无法完成编译。
2.如果一个类内成员变量是static的,但不需要将其设定为常量(const),那么这个变量声明于头文件内,初始化(定义/实现)写在对应的cpp源文件中。
举个例子:
// Scanner.hpp
class Scanner {
public:
static int line;
...
};
// Scanner.cpp
#include "Scanner.hpp" int Scanner::line = ;
...
这样的实现方式给了类实现者一种相对的自由。这样就可以针对不同的实现文件实现不同的类内static字段初始化。
比如有两个Scanner实现文件: Scanner1.cpp 和 Scanner2.cpp,那么这两个源文件分别#include "Scanner.hpp",就可以分别实现各自的类内line值初始化。当然,在实际应用时,切不可同时使用Scanner1和Scanner2,因为这样会发生符号表重定义冲突(因为两个cpp文件均实现了Scanner,符号表内重复填充属性字段)。
需要注意的是,此时不能将上述line的初始化写在头文件(Scanner.hpp)里。道理类似,因为编译器发现这个字段并不是const的,也就是说这个字段可以被不同的实现文件(cpp文件)来具体确定其初始值,那么编译器就不负责在声明阶段对其实现初始化,因此在头文件内初始化一个类内非const的static成员变量是非法的。
C++11类内static成员变量声明与定义的更多相关文章
- 类的static成员变量和成员函数能被继承吗
1. 父类的static变量和函数在派生类中依然可用,但是受访问性控制(比如,父类的private域中的就不可访问),而且对static变量来说,派生类和父类中的static变量是共用空间的,这点 ...
- c++ 类内static成员初始化
类内部的static成员,除了为const static 且为整数类型(int char bool)可在类内部初始化. 其他的都建议在对应的cpp文件中进行初始化. test.h #ifndef TE ...
- 【C++】const,static和static const类型成员变量声明及其初始化
1)const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间 void f1() { ; cout<<x<<endl; ...
- static 成员变量、static 成员函数、类/对象的大小
一.static 成员变量 对于特定类型的全体对象而言,有时候可能需要访问一个全局的变量.比如说统计某种类型对象已创建的数量. 如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个全局变量 ...
- C++ static、const和static const类型成员变量声明以及初始化
C++ static.const和static const 以及它们的初始化 const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间. sta ...
- android 20 Intnet类重要的成员变量
Intnet类重要的成员变量: <intent-filter> <action android:name="android.intent.action.MAIN" ...
- 测试 Java 类的非公有成员变量和方法
引言 对于软件开发人员来说,单元测试是一项必不可少的工作.它既可以验证程序的有效性,又可以在程序出现 BUG 的时候,帮助开发人员快速的定位问题所在.但是,在写单元测试的过程中,开发人员经常要访问类的 ...
- C++中的static 成员变量的一些注意点
C++中的static成员变量主要用来为多个对象共享数据 例: #include <iostream> using namespace std; class Student{ public ...
- java static成员变量方法和非static成员变量方法的区别
这里的普通方法和成员变量是指,非静态方法和非静态成员变量首先static是静态的意思,是修饰符,可以被用来修饰变量或者方法. static成员变量有全局变量的作用 非static成员变量则 ...
随机推荐
- 刷题70. Climbing Stairs
一.题目说明 题目70. Climbing Stairs,爬台阶(楼梯),一次可以爬1.2个台阶,n层的台阶有几种爬法.难度是Easy! 二.我的解答 类似的题目做过,问题就变得非常简单.首先用递归方 ...
- Python - 用python实现split函数
# pattern支持字符或者字符串 def my_split(string, pattern): ret = [] len_pattern = len(pattern) while True: in ...
- Linux安装Redis服务
下载:wget http://download.redis.io/releases/redis-5.0.5.tar.gz 解压:tar -zxvf redis-5.0.5.tar.gz 进入redi ...
- centos openoffice 的启动
https://blog.csdn.net/resolute123/article/details/77304973
- 如何在app.js 和其他页面中更改globalData的值
它不能用this.setData方法更改值,该方法只能更改data:{}对象(而且在app.js中无法使用该方法),因此用app.globalData.isLogin = true;
- 「JSOI2015」salesman
「JSOI2015」salesman 传送门 显然我们为了使收益最大化就直接从子树中选大的就好了. 到达次数的限制就是限制了可以选的子树的数量,因为每次回溯上来都会减一次到达次数. 多种方案的判断就是 ...
- 批量导出存储在msdb库的SSIS包
http://blog.51cto.com/ultrasql/1924464 use msdb go IF OBJECT_ID('msdb.dbo.usp_ExportSSISPkgs') IS NO ...
- 使用$.ajax时的注意事项
做PHP难免接触js,我也是这样,使用ajax的时候,我比较习惯使用$.ajax({}),这种方式,因为通用性较强.有时候会较少使用js,隔一段时间后再使用,有些细节内容容易模糊不清,这一次,我又忘记 ...
- Linux中命令备份mysql形成文件
基于龙哥(Thomas)的总结: mysqldump -u 用户名 -p密码 数据库名>bbs87.sql | tar -zcvf bbs87.tar.gz bbs87.sql 通过词条命令可以 ...
- PowerDesigner每点击一次就会提示打印错误对话框
把服务启用了就好了: 重启软件