C++ const
1.const 修饰变量
- int base = 0;
- // 定义常量(类中的只读变量 只能且必须 在初始化列表中initialize)
- // const常量只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以const定义的常量
- // 在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
- const int a1 = 1; // 编译器可以对它进行类型安全检查(宏常量只是简单的替换,可能会产生意料不到的错误)
- int const a2 = 1;
- // 修饰指针
- int * const b1 = &base;
- // 同时修饰值和指针
- int const * const c1 = &base;
- const int * const c2 = &base; // const修饰记忆:关键字左边的,本身在最左边时修饰右边
2.const 修饰函数(参数、返回值、函数本身)
- class Code
- {
- CString m_code;
- public:
- Code() {}
- ~Code() {}
- const CString* getCode(const CString& src)const;
- void setCode(const CString& src);
- };
void Code::setCode(const CString& src)- {
- m_code = src;
- }
- const CString* Code::getCode(const CString& src) const
- {
- // error
- //src = result; // const修饰的变量只读,且在只读函数内
- //m_code = src; // const修饰的类成员函数 不能修改成员
- //setCode(src); // const修饰的类成员函数 只能调用只读成员函数
- return &m_code;
- }
getCode()函数的返回值必须用 const CString* re = code.getCode( _T(“GB1001”) ); 或者写成 auto re = code.getCode( _T(“GB1001”) );
这种只读的保证是编译器做的限制,少数情况下要在只读函数内修改对象的属性,可以这么做:
- const CString* Code::getCode(const CString& src) const
- {
- // 1.mutable关键字修饰 mutable int value;
- // 2.绕过编译器的限制
- Code* p = (Code*)this; // 关键在于this强转为Code*
- p->setCode(src);
- return &m_code;
- }
const和函数重载
- void Code::fun(int a)const // 可以重载,根据对象是否只读区别
- {}
- void Code::fun(int a)
- {}
- void Code::fun(const int a) // 无法重载
- {}
- void Code::fun(int a)
- {}
3.const修饰对象
const修饰的对象只能访问 类中的只读函数,不能修改变量。较好的设计应该是用const限定方法,不限定对象,类中的属性只能通过方法 Get() 或 Set()
4.只读迭代器
5.const和智能指针
6.const 在C语言和C++中的不同
C++中的const一般被看成编译期的常量,不为const分配空间, 只是在编译的时候将值保存在符号表中,并在适当的时候折合在代码中
C++中, 是否为const分配空间要看具体情况,若加上关键字extern或者取const变量地址,编译器就要为const分配存储空间
C语言中的const是一个不能被改变的普通变量,会占用存储空间
- const int size = 10;
- int array[size] = { 0 }; // C语言中error: 编译器不知道编译时的值(数组下标必须明确)
7.const_cast 关键字
- // const_cast用来移除变量的const或volatile限定符:
- // 使用const_cast再写的后果是未定义的,const_cast的目的并不是为了让你去修改一个本身被定义为const的值,
- // 因为这样做的后果是无法预期的。const_cast的目的是修改一些指针/引用的权限,
- // 如果我们原本无法通过这些指针/引用修改某块内存的值,现在你可以了。
- const int a = 1;
- //int* temp = a; // error
- int* pa1 = const_cast<int*>(&a); // 去除const限制
- int* pa2 = (int*)&a; // 传统方式去除const限定
- *pa1 = 10;
- int modify1 = a; // 1,这里直接被替换成常量表达式,不再从地址中取值(const常量引入的初衷是替代#define)
- *pa2 = 100;
- int modify2 = a; // 1