你所不知道的 const

1. const对象的初始化

const 常量是不可修改的,也就是说only read,例如

const int nBuffSize = 512;

nBuffSize = 0; //error 
就是因为const 常量不能修改,所以定义时必须初始化

2. const对象的文件局部性

默认在全局作用域中定义的非const变量可以在整个程序中访问,例如

//file1.c

int nCounter;

//file2.c

extern int nCounter;

++nCounter;

但是在全局作用域中声明的const变量

是定义的文件局部变量,只能被该文件使用,不能被其他文件使用。可以通过指定const变量为extern,就可以在全局中使用,如下

//file1.c

extern const int nCounter = 1024;

//file2.c

extern int nCounter;

非const变量默认为extern,要使const变量能够在其他文件中访问,必须显示地指定它为extern

3. 指向const对象的指针和const指针

先看下面的例子

const int *p;

int * const p;

第一个就是指向的内容为const,而第二个是指针为const

另外要注意:不能使用void*指针保存const对象的地址,必须使用const void*,如下

const int nBuff = 42;

const void* pv1 = & nBuff;

void * pv2 = &nBuff;  //error 

4.const隐式转换

当使用非const对象初始化const对象的引用时,可以将非const对象转换为const对象,如下

int i;

const int ci = 0;

const int &j = i;

const int *p = &ci;

当要使用非const变量初始化const变量,必须要将非const变量初始化,如下

int i = 123;

const int m = i;

5. 强制类型转换const_cast

const_cast就是隐式转换掉表达式的const性质,假设有函数string_copy,我们对其char*参数只读不写

	const char* pc_str = "hello world!";
	char* pc = string_copy(const_cast<char*>(pc_str));

6. const形参

在调用函数的时候,如果函数使用非引用的非const形参,则可以传递const实参也可以额传递非const实参,如下:

	int rgd(int, int);
	const int i = 3, j = 6;
	int k = rgd(3, 6);
这里传递的实参类型都为const int,因为初始化复制了初始化的值,可用const对象初始化非const对象,反之亦然。

如果将形参定义为非引用的const类型,不可以改变实参的局部副本,由于实参仍是以副本的形式传递,因此传递给函数的既可以是const对象也可以是非const对象。

利用const引用形参可以避免复制实参,因为对于大部分的类类型或者大型数组,复制的效率太低下了,使用引用形参可以直接访问实参对象,而无需复制它,如下

int GetSqListElem(const SqList &L, const ElemType data); //得到线性表中数据为data的第一个索引位置
第一个形参可以避免复制结构体L,使用const引用可以避免复制,同时避免修改实参参值,第二个虽然使用了const 但是没有使用引用,所以还是会复制实参

7. const static成员

一般,类的static成员,是不能在类的定义体中初始化,相反static数据成员通常在定义时初始化,整型const static数据成员就可以在类的定义体中进行初始化:

typedef double Money;
class account
{
public:
	account(){};
	~account(){};

	Money balance(){ return bal; }
	static double rate(){ return interestRate; }
	static void rate(double);
private:
	typedef long double Money;
	Money bal;
	static double interestRate;
	static const int period = 30;
	double daily_tbl[period];
};

const static数据成员在类的定义体中初始化时,该数据成员仍必须在类的定义体外进行定义,在类内部指定初始化值,成员的定义不必再指定初始值,如下

const int account::period;

你所不知道的 const

上一篇:nil和NSNull


下一篇:iOS 调试_模拟器与真机的区分