C++const用法总结 (一)

2014-11-24 01:35:50 · 作者: · 浏览: 4

一、关于一般常量
声明或定义的格式如下:
const <类型说明符> <变量名> = <常量或常量表达式>; [1]
<类型说明符> const <变量名> = <常量或常量表达式>; [2]
[1]和[2]的定义是完全等价的。
例如:
整形int(或其他内置类型:float,double,char)
const int bufSize = 512;
或者
int const bufSize = 512;
因为常量在定义后就不能被修改,所以定义时必须初始化。
bufSize = 128; // error:attempt to write to const object
const string cntStr = "hello!"; // ok:initialized
const i, j = 0; // error: i is uninitialized const
非const变量默认为extern。
const 对象默认为文件的局部变量。要使const变量能够在其他的文件中访问,必须显式地指定它为extern。
例如:
const int bufSize = 512; // 作用域只限于定义此变量的文件

extern const int bufSize = 512; // extern用于扩大作用域,作用域为整个源程序(只有extern 位于函数外部时,才可以含有初始化式)

二、关于数组及结构体
声明或定义的格式如下:
const <类型说明符> <数组名>[<大小>]…… [1]
<类型说明符> const <数组名>[<大小>]…… [2]
[1]和[2]的定义是完全等价的。
例如:
整形int(或其他内置类型:float,double,char)
const int cntIntArr[] = {1,2,3,4,5};
或者
int const cntIntArr[] = {1,2,3,4,5};
struct SI
{
int i1;
int i2;
};
const SI s[] = {{1,2},{3,4}};
// 上面的两个const都是变量集合,编译器会为其分配内存,所以不能在编译期间使用其中的值(例如:int temp[cntIntArr[2]],这样的话编译器会报告不能找到常量表达式)


三、关于引用
声明或定义的格式如下:
const <类型说明符> &<变量名> = …… [1]
<类型说明符> const &<变量名> = …… [2]
[1]和[2]的定义是完全等价的。
例如:
const int i = 128;
const int &r = i;(或者 int const &r = i;)
const 引用就是指向const 对象的引用。
普通引用不能绑定到const 对象,但const 引用可以绑定到非const 对象。
const int ii = 456;
int &rii = ii; // error
int jj = 123;
const int &rjj = jj; // ok
非const 引用只能绑定到与该引用同类型的对象。
const 引用则可以绑定到不同但相关的类型的对象或绑定到右值。
例如:
1.const int &r = 100; // 绑定到字面值常量
2.int i = 50;
const int &r2 = r + i; // 引用r绑定到右值
3.double dVal = 3.1415;
const int &ri = dVal; // 整型引用绑定到double 类型
编译器会把以上代码转换成如下形式的编码:
int temp = dVal; // create temporary int from double
const int &ri = temp; // bind ri to that temporary


四、关于指针
1.指向const 对象的指针(指针所指向的内容为常量)
声明或定义的格式如下(定义时可以不初始化):
const <类型说明符> *<变量名> …… [1]
<类型说明符> const *<变量名> …… [2]
[1]和[2]的定义是完全等价的。
例如:
const int i = 100;
const int *cptr = &i;
或者
int const *cptr = &i; [cptr 是指向int 类型的const 对象的指针]
允许把非const 对象的地址赋给指向const 对象的指针,例如:
double dVal = 3.14; // dVal is a double; its value can be change
const double *cdptr = &dVal; // ok;but can't change dVal through cdptr
不能使用指向const 对象的指针修改基础对象。然而如果该指针指向的是一个没const 对象(如cdptr),可用其他方法修改其所指向的对象。
如何将一个const 对象合法地赋给一个普通指针???
例如:
const double dVal = 3.14;
double *ptr = &dVal; // error
double *ptr = const_cast(&dVal);
// ok: const_cast是C++中标准的强制转换,C语言使用:double *ptr = (double*)&dVal;


2.const 指针(指针本身为常量)
声明或定义的格式如下(定义时必须初始化):
<类型说明符> *const <变量名> = ……
例如:
int errNumb = 0;
int iVal = 10;
int *const curErr = &errNumb; [curErr 是指向int 型对象的const 指针]
指针的指向不能被修改。
curErr = &iVal; // error: curErr is const
指针所指向的基础对象可以修改。
*curErr = 1; // ok:reset value of the object(errNumb) which curErr is bind
3.指向const 对象的const 指针(指针本身和指向的内容均为常量)
声明或定义的格式如下(定义时必须初始化):
const <类型说明符> *const <变量名> = ……
例如:
const double pi = 3.14159;
const double dVal = 3.14;
const double *const pi_ptr = π [pi_ptr 是指向double 类型的const 对象的const 指针]
指针的指向不能被修改。
pi_ptr = &dVal; // error: pi_ptr is const
指针所指向的基础对象也不能被修改。
*pi_ptr = dVal; // error: pi is const


五、关于一般函数
1.修饰函数的参数
class A;
void func1(const int i); // i不能被修改
void func3 (const A &rA); // rA所引用的对象不能被修改
void func2 (const char *pstr); // pstr所指向的内容不能被修改
2.修饰函数的返回值
返回值:const int func1(); // 此处返回int 类型的const值,意思指返回的原函数里的变量的初值不能被修改,但是函数按值返回的这个变量被制成副本,能不能被修改就没有了意义,它可以被赋给任何的const或非const类型变量,完全不需要加上这个const关键字。
[*注意*]但这只对于内部类型而言(因为内部类型返回的肯定是一个值,而不会返回一个变量,不会作为左值使用,否则编译器会报错),对于用户自定义类型,返回值是常量是非常重要的(后面在类里面会谈到)。
返回引用:const int &func2(); // 注意千万不要返回局部对象的引用,否则会报运行时错误:因为一旦函数结束,局部对象被释放,函数返回值指向了一个对程序来说不再有效的内存空间。
返回指针:const int *func3(); // 注意千万不要返回指向局部对象的指针,因为一旦函数结束,局部对象被释放,返回的指针变成了指向一个不再存在的对象的悬垂指针。
六、关于类
class A
{
public:
void func();
void func() c