①.const 修饰变量
用 const 修饰一个变量,表示该变量一旦创建,则值不可以被更改;定义一个 const 变量,则必须进行初始化。
const int a = 12;//编译时初始化const int b = getsize();//运行时初始化a = 10;//报错,const 变量禁止赋值
②.初始化和 const
当用一个对象对初始化另外一个对象时,他们是不是 const 都无关紧要,因为拷贝不改变原对象内容。
int i = 42;const int c = i;// i 的值 拷贝给 cint j = c;
③.extern const
一个对象可以有多次声明,但定义只能一次。如果要在多个文件之间共享 const 对象,必须在变量定义之前添加 extern 关键字。
// test1.cppextern const int a = 10; //定义一个 const 变量 a,该常量能被其他文件访问//test2.cppextern const int a;// 仅声明一个 const 变量 a,该常量的定义可以在其他文件中找到
禁止在头文件中用 extern 定义变量,若该头文件被多个文件包含时,将会出现重复定义错误。
// test.hextern const int a = 10;// test1.cpp#include "test.h"// 编译出错,重复定义错误
④.const 和 #define
#define 是在编译的预处理阶段起作用;而 cons t是在 编译、运行的时候作用。
#define 只是简单的字符串替换,没有类型检查;const 定义的常量,在编译时进行严格的类型检验,可以避免出错。
#define 只是进行展开,有多少地方使用就替换多少次,内存中有若干个备份;const 定义的只读变量在程序运行过程中只有一份备份。
因此对于单纯常量,最好以 const 对象替换 #define。
03PARTconst 与引用①.const 的引用
可以把引用绑定到 const 对象上,称为对常量的引用;对常量的引用不能被用作修改它所绑定的对象。
const int c = 1024;const int &r = c;// r 是绑定到 c 的引用
②.引用非 const 对象
常量引用仅对引用可参与的操作进行了限定,对引用对象本身是不是常量未做限定。
int i= 12;const int &r = i;// r 是常量引用,但绑定的对象 i 非 const
04PARTconst 与指针
①.指向常量的指针
要想存放常量对象的地址,只能使用指向常量的指针;指向常量的指针不能用于改变其所指对象的值。
const a = 3;// a 是一个常量int *p = &a;//错误 , p 是一个普通指针const int *p1 = &a;// p1 是一个指向常量的指针
同引用,指向常量的指针对其所指对象是否是常量没有限制。
②.顶层 const
当关键字 const 出现在星号的右边,则为:顶层 const ;表示指针本身是个常量,不能改变指针本身的值。
int i = 2;int * const ptr= &i;//ptr是一个顶层const,将一直指向 i,不能改变 ptr 的值
③.底层 const
当关键字 const 出现在星号的左边,则为:底层 const ;表示指针所指对象是个常量,不能改变所指对象的值。
int i = 2;const int * ptr= &i;//ptr是一个底层const,可以改变 ptr 的值,但不能改变所指对象的值
05PARTconst 与函数
①.const 修饰函数参数
可以表示传递过来的参数,在函数内不可以被修改;并无实际意义,因为函数会自动产生临时变量复制实参值,并不会对原对象进行更改。
void int f1(const int a){ // 在函数内不可以改变 a 的值}
可以表示参数指针所指的内容为常量,不可以改变。
void int f2(const int *a){ // 在函数内不可以改变 *a 的值}
可以表示参数指针本身为常量,不可以更改;也无实际意义,因为参数指针也是形参。
void int f3(const int * const a){ // 在函数内不可以改变 a 的值}
自定义类型的参数传递,需要临时对象复制参数,对于临时对象的构造,需要调用构造函数比较浪费时间,因此采取引用传递的方法。可以用 const 限定 增加效率同时防止被修改。
void int f4(const T & a){ // 在函数内不可以改变 a 的值}
②.const 修饰函数返回值
函数返回值是值传递时,用 const 修饰返回值没有任何意义,因为函数会把返回值复制到外部临时的存储单元中。
const int f1();//
函数返回值类型是指针并用 const 修饰时,该返回值只能被赋给加const 修饰的同类型指针。
const int * f2();//调用时,const int * p1 = f2();int * const f3();//调用时,int * const p2= f3();
一般情况下,函数的返回值为某个对象时,如果将其声明为 const 时,用于限制不能将函数表达式作为左值使用。
const int & min ( int &i, int &j);min(a,b) = 4;//出错
06PARTconst 与类
①.const 修饰成员变量
用 const 修饰类的成员变量,表示成员常量,不可以被修改,也只能在初始化列表中被赋值。
class A{ const int val;//成员常量不可以被修改 A(int v):val(x){};//只能在初始化列表中赋值}
②.const 修饰成员函数
用 const修饰类的成员函数,则该成员函数不能修改类中任何成员,一般写在函数的最后来修饰。
class A{ void function() const;//不可以修改对象的成员变量,也不能调用非 const 成员函数}
③.const 修饰类对象
用 const 修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改;对于对象指针和对象引用也是一样。
用 const 修饰的对象,该对象的任何非 const 成员函数都不能被调用。
class A{ void function1() const; void function2() ;}const A *obj = new A();A->function1();//正确A->function2);//错误,const 对象只能调用 const 成员函数
④.const 修饰成员函数修改成员变量
可以使用 mutable 关键字修饰成员,则该变量在 const 成员函数中也可以被修改。
class A{ mutable int _ct; void function() const{ _ct++;//正确 };}
07PARTconst 转换
①.去 const 限定
使用 const_cast 可以去除变量的 const 限制:常量指针被强制转为非常量指针,仍然指向原来对象;常量引用被强制转为非常量引用,仍然指向原来对象;常量对象被强制转为非常量对象。
const A *obj = new A();//A 指向的对象不可用被更改A * ptr = const_cast(obj);// ptr 和 obj 指向同一个对象,ptr 可以更改对象const A a;A b = const_cast(a);//去 const 属性后赋值给一般变量
②.增加 const 限定
也可以使用 const_cast 、 static_cast 将非 const 对象增加 const 限定。
A *obj = new A();const A * ptr = static_cast<const A*>(obj);//obj 增加 const 限定
扫码关注持续获取最新文章c++学习 算法与数据结构