Thinking in C++ 学习笔记 类中的const
1. 类里的const
(1)在一个类里,const意味着“在这个对象生命周期内,它是一个常量”。
(2)在一个类里建立一个普通的(非static)const时,不能给它初值,初始化工作必须在构造函数的初始化列表里进行。初始化列表发生在构造函数的任何代码运行前,这(初始化列表)是初始化所有const的地方。
(3)因为在类对象里进行存储空间的分配,编译器不知道const成员的内容是什么,所以不能把它用作编译期间的常量.
可以认为内部类型有一个构造函数。比如 : int data(10);
2. 编译期间的常量
类中使用const不能使类具有编译期间的常量。解决办法是引入static,它意味着“不管类被创建多少次,都只有一个实例”。一个内部类型的static const可以被看做一个编译期间的常量。
旧代码中的“enum hack”
旧版本的c++中不支持static const ,解决办法是使用不带实例的无标记enum(通常称为“enum hack”)。一个枚举编译期间必须有值,它在类中局部出现,而且它的值对于常量表达式是可以用的,如:
Class Bunch{
Enum { size = 100 };//这里使用的enum保证不占用对象的存储空间。
Int i[size];
};
3. const对象和成员函数
(1)把一个对象声明为const其数据成员在它的生命期间不可被改变。
如果声明一个成员函数为const,则该成员函数不能改变数据成员,可以为const对象所调用。编译器不允许const对象调用非const成员函数,因为它可以改变数据成员。
(2)编译器强迫程序员定义const成员函数时重申const,否则编译器把它看成一个不同的函数。
const成员函数可以被相同参数表的非const成员函数重载。例如:
class Screen{
public: char get(int x,int y);
char get(int x,int y) const;
};
(3)不修改数据成员的热播和函数都应该把它们声明为const。
构造函数和析构函数都不是const,因为它们总是对对象做些修改。
4. 按位const(bitwise const)和按逻辑const(logical const).
(1),按位const:对象中的每个位是固定的,所以对象的每个位的映像从不改变。对应方法:强制转换const: ((y*)this)->j++; 或者 (const_cast<Y*>(this)->i++;
(2),按逻辑(有时也成按成员)const:虽然整个对象从概念上讲是不变的,但是某个成员可能改变。对应方法:mutable int j;
关键字mutable指定一个特定的数据成员可以在一个const对象里改变。
总结:c中的const被认为是一个不能改变的变量,而不是一个编译期间的常量。C++中的const首先意味着一个“编译期间的常量”,因为它甚至可能没有分配存储空间。
Volatile
Volatile和const的用法一样,它的意思是“编译器认识的范围外,这个数据可以被改变”。
象const一样,可以对数据成员、成员函数和对象本身调用volatile,可以对volatile对象调用volatile成员函数。
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量