* 将某些东西声明为const可帮助编译器侦测出错误的用法。
* 假如当const和non-const成员函数有着相同的用法时,non-const的成员函数调用const版本可以避免代码重复
const出现在*左侧,表示被指物是常量;出现在*右侧,表示指针是常量。也可能同时出现在*两侧。
被指物是常量时,const写在类型的前后都是可以的
const int * num1 = 3;
int const * num2 = 3;
如果两个成员函数如果只是常量性不同,可以被重载
class ConstTest{
public:
const char& operator[](std::size_t postion) const{
//验证等其他操作
std::cout<<"const"<<std::endl;
return text[postion];
}
char& operator[](std::size_t postion){
//验证等其他操作
std::cout<<"no const"<<std::endl;
return text[postion];
}
private:
std::string text{"hello"};
};
void print(const ConstTest& ctb){
std::cout<<ctb[0]<<std::endl;
}
void print(ConstTest& ctb){
std::cout<<ctb[0]<<std::endl;
}
int main()
{
const ConstTest c1;
print(c1);// const t
ConstTest c2;
print(c2);// no const t
return 0;
}
避免const和no-const成员函数中的重复
由上述代码中的运算符重载函数可知,除了返回字符,还有验证等其他操作,两个函数中明显这部分是重复的,大部分人可能会抽离出这部分代码重新写封装成一个函数,让运算符重载函数调用,但无形之中也增加函数调用等等各种操作。解决办法如下:
class ConstTest{
public:
const char& operator[](std::size_t postion) const{
std::cout<<"const"<<std::endl;
std::cout<<"验证等重复性工作"<<std::endl;
return text[postion];
}
char& operator[](std::size_t postion){
std::cout<<"非const-"<<std::flush;
return const_cast<char&>(
static_cast<const ConstTest&>(*this)[postion]
);
}
private:
std::string text{"hello"};
};
void print(const ConstTest& ctb){
std::cout<<ctb[0]<<std::endl;
}
void print(ConstTest& ctb){
std::cout<<ctb[0]<<std::endl;
}
int main(int argc, char *argv[])
{
const ConstTest c1;
print(c1);
ConstTest c2;
print(c2);
}
为了解决代码重复的问题,用非const版本调用const版本代码。(非const调用const本身就是安全的,反之,则不是),上述代码中,首先将*this从非const类型静态类型转换(安全)转换为const类型,这是text[postion] 调用的是const版本的重载函数,调用完成返回时在利用 const_cast去掉const。