C++中static、const、static const修饰变量作用详解(转)
2015-06-16 22:25
555 查看
C++中static、const、static const修饰变量作用详解
C++中类的变量可以通过static、const、static const来修饰,不同的修饰在不同的情况下表示不同的含义。下面7少带大家一块详细解读一下他们的用处。首先我们需要先了解程序运行期间的内存分区:
代码区:存放CPU指令码。
常量区:存放只读常量,该区只读,不可写。
静态区:存放静态变量。该区在程序编译完成后就决定了其大小,程序运行期间该区的大小不会变。该区可读写。
动态区:又分为堆区和栈区,程序运行期间其大小处于动态变化中。处于该区的变量也会时而被创建时而被销毁。
static关键字:
经过static修饰的变量会作为类的属性而不是实体属性存在。static修饰的变量作为程序运行时的静态变量,存在于内存的静态区,静态区的数据初始化工作由操作系统在加载完程序后执行main函数前进行。操作系统在加载完程序后,将常量区中存放的变量初值复制给静态变量,完成其初始化。
static修饰的变量通过int ClassName::value=1这种方式进行初始化。此时不再需要static 关键字。程序运行期间也可以对变量进行赋值操作。
const关键字:
经过const修饰的属性,顾名思义是指常量。const修饰的属性仍然属于实体属性,所以其初始化工作,需要由构造函数的初始化列表中完成。而且也只能在构造函数的初始化列表中初始化,运行期间将不 能再对const属性进行修改。值得注意的是,虽然经过const修饰,但是因为变量属于实体属性,而实体对象存在于动态区,所以const属性也属于动 态区,所以可以通过取址直接操作指向的内存的值,以绕过编译器对其只读的限制检查。
static const关键字:
static const 和 const static 含义相同。static const有两种用法,一种是作为预编译声明,一种是作为类的静态常量属性。
当作为预编译声明时,static const 属性必须在声明时即指定值,而且类型仅限基本数据类型。用法如下:
class A { static const int a =1; }
此时相当于C语言中的 #define a 1 宏定义了一个宏变量a,但是C++的这种方式比C的#define的优势在于,可以对类型进行检查和限制,减少了编译期间因为类型隐士转换而造成的潜在风险。
此时的 const static常量既不存在于动态区也不存在与静态区(应该是存在于常量区或代码区。。。),而是由编译器在编译期间就直接进行了值替换。也因为这个原因不可以对其进行取地址操作,因为他根本没有地址。
另一种用法是作为类的静态常量属性,此时,不能在类的声明处进行初始化。而需要通过 int ClassName::value = 1;的方式进行初始化赋值。
const static常量存在于内存的常量区,有操作系统加载程序时,加载到内存的常量区。所以可以对其取址,但是不能对该区的内存进行写操作,因为这个区从操作系统级进行了只读限定,任何对该内存区的写操作会导致程序崩溃。
总结:
static const 作为预编译声明使用时,相当于C的#define,但是需要编译器进行类型检查,保证了程序的健壮性。此时其只能用基本数据类型。static const 作为类的常量属性,因为常量区是在程序真正执行代码前进行初始化,所以其也必须是基本数据类型。
static const 和const的区别是:
const声明的只读变量,在程序运行期间不能对其进行写操作,写操作将无法通过编译,也就是说它是通过编译器控制的只读,所以如果想下面这样:A a; int * pa = (int*)&a.a; *pa = 2;
则可以绕过编译器修改他的值。
但是 static const属性虽然也可以取址,但是对其写操作将会导致程序崩溃。因为static const 存在于常量区,而const存在于动态区。
static const 和 static的区别
static 存在于静态区,该区可以进行写操作,其初始化的值也会存在常量区,程序启动后由操作系统从常量区取值赋值给static变量。补充
const成员属性实在对象生成时分配内存的,而不是在编译期间分配内存,则必须在构造函数中进行初始化static属于类而不属于任何一个对象,所以不是在定义对象是对其初始化,因此不能再构造函数中对其初始化,正确的初始化方法是在定义成员函数的文件中进行初始化
相关文章推荐
- PCA人脸识别学习及C语言实现
- [C/CPP系列知识] Type difference of character literals 和 bool in C and C++
- C++中重载/覆盖/隐藏的区别
- C语言笔记之指针的初步认识
- C++下高效率int转成string
- 开始学习C++心得实例(4)
- c++异常处理机制
- 【leetcode c++】19 removeNthFromEnd
- c++容器之vector
- [C/CPP系列知识] C++中extern “C” name mangling -- Name Mangling and extern “C” in C++
- C++ Virtual介绍
- C++ Virtual介绍 分类: C/C++ 2015-06-16 21:36 26人阅读 评论(0) 收藏
- FreeGLUT Tips: Resolve compile error C2664: cannot convert argument 2 from '_TCHAR *[]' to 'char **'
- C语言和Fortran语言的差异
- 迷宫的最短路径 代码(C++)
- 一起talk C栗子吧(第十八回:C语言实例--输出十六进制)
- C++标准库之Unities-笔记2
- C++ extern/static/const
- Bjarne Stroustrup对C++程序员的忠告
- 多态原理探究-从C++编译器角度理解多态的实现原理