const是编程过程中应该尽可能多使用的关键字,它指定一个不可变对象,编译器会强行执行这个约束,来增强的代码的健壮性。const可用来修饰变量、参数,函数返回值、函数本身,可谓多才多艺 。
1. const修饰变量
- 在Effective C++条款2中讲到,尽量使用const声明常量来替换#define声明的宏定义常量。(inline替换#define的函数)
#define pi 3.1415926 const double pi = 3.1415926
- const修饰指针
char s[] = "hitsz" char* p = s; const char* p = s; //p指向可变,指向内容不可变 char* const p =s; //p指向不可变,指向内容可变 const char* const p = s;// 二者均不可变
- const修饰迭代器
vector<int>vec; const vector<int>::iterator it = vec.begin(); // 等同于T* const,迭代器不可变 *it = 100; it++; //error!!!it 是const vector<int>::const_iterator it = vec.begin(); //等同于const T* *it = 100; //error!!! 内容不可变 it++;
2.修饰函数形参
使用const修饰函数形参,可防止该参数在函数中被意外修改,起保护作用。例如在字符串拷贝时,我们不希望在过程中改变原字符串:
void stringcp(char* strdes, const char* strsource)
3.修饰函数的返回值
const来修饰返回的指针或引用,保护指针指向的内容或引用的内容不被修改,也常用于运算符重载。归根究底就是使得函数调用表达式不能作为左值。
#include <iostream>
using namespace std;
class A {
private:
int i;
int j;
public:
A(){i=0; j = 10;}
int & get_i(){ return i; }
const int & get_j(){ return j; }
};
void main(){
A a;
cout<<a.get()<<endl; //数据成员值为0
a.get_i()=1; //尝试修改a对象的数据成员为1,而且是用函数调用表达式作为左值。
cout<<a.get()<<endl; //数据成员真的被改为1了,返回指针的情况也可以修改成员i的值,所以为了安全起见最好在返回值加上const,使得函数调用表达式不能作为左值
a.get_j() = 100;// 错误!!!!
}
4.const修饰成员函数
任何不会改变数据成员的函数都应该声明为const,防止函数意外修改了数据成员(mutable成员变量除外)。将成员函数声明为const还有以下两个优点,第一:它使得函数更易理解,很容易得知那个函数可以改变对象内容哪个函数不能改变。第二:使操作const对象成为可能,因为const对象不能访问非const函数,只有const成员函数才能处理const对象。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <limits.h>
#include <iostream>
using namespace std;
class MyIntArray
{
private:
static const int a = 100;
int p[a];
public:
MyIntArray()
{
for( int i = 0 ; i < a ; i++ )
{
p[i] = i;
}
}
const int & operator [](int n) const
{
return p[n];
}
int & operator [](int n)
{
return p[n];
}
};
int main(int argc, char *argv[])
{
MyIntArray array;//定义一个非const对象
cout<<array[20]<<endl;//输出20
array[20] = 6;//正确,调用非const版本的[]
cout<<array[20]<<endl;//输出6
const MyIntArray carray;//定义一个const对象
cout<<carray[20]<<endl;//输出20
carray[20] = 6;//错误!调用const版本的[]操作符
cout<<carray[20]<<endl;
}
const成员函数注意事项:
1. const成员函数不可调用非const成员函数
2. const成员函数若返回值得引用,则一定是const引用
3.如要在const成员函数内修改成员变量,则需将成员变量设为mutable类型。
5.const-cast的使用
const_cast是一种C++运算符,主要是用来去除复合类型中const和volatile属性(没有真正去除)。变量本身的const属性是不能去除的,要想修改变量的值,一般是去除指针(或引用)的const属性,再进行间接修改。
用法:const_cast<type>(expression)
通过const_cast运算符,也只能将const type*转换为type*,将const type&转换为type&。
const int a = 3;
int &r = a; //error r 要是const 引用
const int& r =a;
int &r = const_cast<int&>(a);// 正确 去除了a的const引用属性
r++;