尽可能使用const
1.const和指针
如果const关键字在星号左边,表示被指物是常量; const T* t
如果出现在星号右边,表示指针自身是常量; T* const t
如果出现在星号两边,表示被指物和指针两者都是常量;const T* const t
总结:const靠近*号,那么申明的指针就是常量。远离*的const就是描述指针的所指量为常量
2.const和迭代器
STL中的迭代器实际上本质是以指针实现的,所以可以把一个迭代器看作是一个指针,可以用指针的性质去套迭代器的性质。
std::vector <int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
const std::vector <int>:: iterator it = vec.begin();
std::vector <int> ::const_iterator iit =vec.begin();
*it =10;
// ++it; 错误
// *iit = 30; 错误
iit++;
这里的it就是常量,*it是可以被改变的;*iit是常量,iit可以被改变。
总结:const_iterator 相当于const T* (指向的内存不能被改变)
const ……iterator 相当于T* const
3.另函数返回一个常量,可以降低因用户错误造成的意外
例如重载*操作符时的声明如下:
const Complex operator* (const Complex& lhs, const Complex& rhs);
返回const对象可以避免像 (a*b)= c 这样的情况发生,通常表现为这样的错误:
if (a*b = c)//实际是想判断是否相等,即应为==而不是=
此时因为a*b返回的对象是const对象,不可修改,因此会报错,使得程序员发现这个错误并修改。
4.通过mutable去除non-static成员变量的bitwise constness约束:
bitwise const认为,成员函数只有在不更改对象的任何成员变量时才可以说是const,也就是它不更改对象内的任何一个bit。
bitwise const正是c++对常量性的定义,因此const成员函数不能更改对象内任何non-static成员变量。
class Text {
public:
std::size_t length() const;
private:
char* pText;
std::size_t textLength;
bool lengthValid;
};
std::size_t Text::length() const {
if (!lengthValid) { //错误,在const函数内要改变textLength和lengthValid的值
textLength = std::strlen(pText);
lengthValid = true;
}
return textLength;
}
这样的code是不能通过bitwsie const的编译器,编译器提示:
cannot assign non-static data member within const funciton ……
如果要使textLength、lengthValid
可以修改,需要用mutable
释放掉non-static成员变量的bitwise const约束:
...
private:
mutable std::size_t textLength; ///mutable的意思就是成员变量可能总是被更改,即使在const成员函数内
mutable bool lengthValid;
...
加上mutable ,编译器报警消失
5. 在const和non-const成员函数中避免重复
一句话就是:利用const函数实现内容,去实现non-const函数,就是需要进行数据类型的转换
const char& operator[] (std::size_t position) const {
... ////函数实现
return text[position];
}
char& operator[] (std::size_t position) {
return const_cast<char&>(static_cast<const Text&>(*this)[posistion]);
}
这里的下面一个操作符,里面有两次转型,第一次用来为*this从其原始类型TextBlock& 转型为const TextBlock&,通过添加const
第二次是从const operator[ ] 的返回值中移除const。