标签:
const在C++中使用十分广泛,不同位置使用的意义也不尽相同,所以想写篇文章对其做一个总结。基本原则:const变量(对象)不能被修改
const在变量中的引入和魔数有关,所谓“魔数”指的是突然出现的一个常量值(也叫字面值常量)。
for(int i = 0; i < 512; i++) { // todo }
const int length = 512; for(int i = 0; i < length; i++) { // todo }
1.2 const常量的作用域:
我们知道,在全局作用域内声明一个变量(此处特指非const修饰的变量),其作用于整个程序,在其他文件中也能被引用,原因是在全局作用域声明一个变量,默认是extern修饰的。
在全局作用域内声明一个const变量,默认不是extern修饰,所以其只能作用于本文件内,若要在其他文件中访问,需要显式声明为extern2. const与引用
基本原则:const引用是指向const变量(对象)的引用const int ival = 1024; const int &refVal = ival;
2.1 const引用可以指向一个相关类型(不是本类型)的const变量
double dval = 3.14; const int &refVal = dval;
3. const与指针
const与指针的关系分为两种:const修饰的指针和指向const对象的指针,二者const的位置不相同3.1 指向const对象的指针(const位于指针符号*前面)
对于一个const对象,必须用一个指向const的指针来指向它。原因在于,const修饰使得对象无法被改变,而指针如果不是指向const的指针,则可以通过指针来修改对象,这是不被允许的。const int ival = 1; const int *ptrVal = &ival;
int *ptr = &val;
int ival = 1; const int *ptrVal = &ival;
3.2 const修饰的指针(const位于指针符号*后面)
int *const ptr;
int ival = 1; int *const ptr = &ival; *ptr = 2; // ok int ivalTwo = 11; ptr = &ivalTwo // error
综上,可以定义一个指向const对象的const指针
const int *const ptr = &ival;
3.3 typedef中易出错的const指针
typedef string *ptr; const ptr s_ptr;
4. const与数组
const与数组的点在于const在定义时必须初始化这个原则,所以使用动态分配数组时,如果数组存储的是const类型的对象,必须进行初始化(使用初始化符号())。5. const与函数返回值
修饰函数的返回值,用于返回一个常量。const int foo();
5.1 返回通过值传递
如果函数返回时采用值传递,比如返回一个int类型,那么函数会把返回的值(比如47)复制到外部临时存储单元中(产生临时副本),所以加const修饰毫无意义int foo(); const int foo();
5.2 返回通过引用传递(并不多见)
如果返回值不是内部类型,通常使用引用传递来返回结果,因为引用传递的是本身,不需要产生临时副本。但需要注意的是,此时仅仅返回一个别名。ClassType &foo(); const ClassType &foo();
const ClassType *foo();
const ClassType *ptr = foo(); //ok ClassType *ptr = foo(); //error
6. const与函数参数
首先需要明确,const修饰的目的就在于保护所修饰的内容不被改变。6.1 值传递
值传递在函数调用时产生一个临时副本,函数中对传入参数的修改和操作是对副本的操作,不改变实参本身的值,所以无需const来保护。值传递的保护很好,但值传递存在缺点,需要产生临时副本,如果传入的是对象,那么需要进行构造、复制、和析构等操作,效率不高。这时候可以考虑引用传递
void foo1(int x); void foo2(ClassType instance); //开销较大
void foo1(const int x); void foo2(const ClassType instance);
6.2 引用传递
通过传入实参的引用,降低开销。因为引用即本身,不需要去产生一个临时副本。void foo1(int &x); void foo2(ClassType &ref);
void foo1(const int &x); void foo2(const ClassType &ref);
void foo1(int x); void foo1(const int &x);
6.3 指针传递
指针传递在保护参数不被修改上和引用传递是一样的,指针传递还有一个功能是可以扩大接收参数的范围:void foo1(const ClassType *ptr);
7. const与类的数据成员
const修饰的数据成员不能在构造函数中进行初始化,只能使用成员初始化列表进行初始化。8. const与类的成员函数
const成员函数中,const位于函数的参数列表后面(函数声明前面表示函数的返回值是一个常量)因为this是指向对象的指针,所以我们需要再次结合const与指针的知识:
(1)const修饰了this,得到const ClassType *this,this指向一个“自认为”是const的对象(也就是本身),所以任何对象(const或者非const)都可以调用一个const成员函数,因为传入的指针都把自身这个对象看作是const对象,所以不能被修改。标签:
原文地址:http://blog.csdn.net/gvfdbdf/article/details/51111854