关于const的各种用法
const T 定义一个常量并且需要初始化
const int v = 10; v = 10 //报错
const T* 指向某个值,不能通过它来改变原来的值
int v = 10; const int * vptr = &v; *vptr = 11; //报错
T * const 说明不能修改这个指针的指向值
int v = 10; int * const vptr = &v; vptr = new int(2); //报错
const T& 常量引用,常量引用不能修改其绑定的值
int i = 5; const int constInt = 10; const int& rConstInt = constInt; //正确,引用及邦定的值都是常量 rConstInt = 5; //错误,不能改变引用所指向的对象1 允许为一个常量引用邦定一个非常量对象、字面值,甚至是表达式;引用的类型与引用所指向的类型必须一致。 int i = 5; int& rInt = i; //正确,int的引用 const int constInt = 10; const int& rConstInt = constInt; //正确,引用及邦定的值都是常量 const int& rConstInt2 = rInt; //正确,用rInt邦定的对象进行赋值 rInt = 30; //这时,rConstInt2、rInt、i的值都为30 //rConstInt2 = 30; //错误,rConstInt2是常量引用,rConstInt2本身不能改变所指向的对象 int i2 = 15; const int& rConstInt3 = i2; //正确,用非常量的对象为其赋值 const int& rConstInt4 = i + i2; //正确,用表达式为其赋值,值为45 i = 20; //此时i=20, rInt = 20, rConstInt4 = 45,说明rConstInt4邦定的是i + i2的临时变量 const int& rConstInt5 = 50; //正解,用一个常量值为其赋值
const T* 和 T * const&
指向常量对象的指针的引用,这可以分两步来理解:1.const T*是指向常量的指针;2.const T*&指向常量的指针的引用。
const int nConstValue = 1; //常量对象 const int nConstValue2 = 2; //常量对象 const int* pConstValue = &nConstValue; //指向常量对象的指针 const int* pConstValue2 = &nConstValue2; //指向常量对象的指针 const int*& rpConstValue = pConstValue; //指向常量对象的指针的引用 //*rpConstValue = 10; //错误,rpConstValue指向的是常量对象,常量对象的值不可改变 rpConstValue = pConstValue2; //正确,此时pConstValue的值等于pConstValue2 //指向常量对象的指针本身是对象,引用可以改变邦定对象的值 int nValue = 5; int nValue2 = 10; int *const constPoint = &nValue; //常量指针 int *const constPoint2 = &nValue2; //常量指针 int *const &rpConstPoint = constPoint; //对常量指针的引用,邦定constPoint //rpConstPoint = constPoint2; //错误,constPoint是常量指针,指针本身的值不可改变 *rpConstPoint = 20; //正确,指针指向的对象可以改变
应用:
1.希望传入一个对象,但又不想函数修改它
方式<1>
void Dealwith(const Data& data) { cout << data.value << endl; //data.value = 5; //错误,data是常量引用,不能改变其邦定的对象 }
这种方式还有一个好处是只有在调用函数的时候会邦定对象,传递的是对象的引用,而不是对象,减少函数调用时对象赋值的花销。
方式<2>
void Dealwith(const Data* pData) { cout << pData->value << endl; //pData->value = 5; //错误,pData是指向常量对象的指针,不能改变其指向的对象 }
这种方式与void Dealwith(const Data& data)的功能相同
方式<3>
Data g_data(20); void Dealwith(const Data*& pData) { cout << pData->value << endl; //pData->value = 5; //错误,pData邦定的是指向常量对象的指针,常量对象的指针不能改变其指向的对象 pData = &g_data; //正确,pData是[指向常量对象的指针]的引用,引用可改变其邦定的对象 }
2.返回一个类的成员,但不希望调用方修改
class MyData { public : MyData(std::string name, Data data) { m_name = name; m_data = data; } const Data* GetData() { return &m_data; } private: std::string m_name; Data m_data; }; MyData mydata("", Data(100)); const Data* pData = mydata.GetData(); cout << pData->value << endl; //pData->value = 100 //pData->value = 50; //错误,pData是指向常量对象的指向,不能改变其指向对象的值