条款03:尽可能使用const
const指定不能被改动的对象,编译器会强制实施这项约束。
char name[] = "April" const char *p = name; //常量数据,非常量指针 char* const p = name; //非常量数据,常量指针
#include <vector> using namespace std; int main(){ vector<int> vec; vec.push_back(0); const vector<int>::iterator iter = vec.begin(); //等价于int* const iter; 常量指针 *iter = 10; //可以改变存储的数据 vector<int>::const_iterator cIter = vec.begin(); //等价于const int* iter; 常量数据 ++cIter; //可以改变指针的指向 system("pause"); return 0; }
const返回值
函数返回常量值,可以避免用户修改造成意外,如操作符*返回常量值,语句(a * b)= c就会编译不通过。
const Number operator* (const Number& lhs, const Number& rhs);
const成员函数
const成员函数,可以使用于const对象。优点:
- 使class成员函数容易理解,明确哪个成员函数可以改动对象;
- 两个成员函数如果只是常量性不同,可以被重载。
#include <iostream> #include <string> using namespace std; class Test{ public: Test(string name):m_name(name){} const char& operator[](int pos) const { return m_name[pos]; }; char &operator[](int pos){ return m_name[pos]; }; private: string m_name; }; int main(){ Test myTest("Hello"); cout << myTest[0]; const Test CmyTest("April"); cout << CmyTest[0]; system("pause"); return 0; }注:函数的返回类型是char的引用而不是char,因为如果函数的返回类型是内置类型,那么改动返回值就不合法。
常量性移除
mutable,在const成员函数内,可以更改mutable声明的成员变量。
class Test{ public: const char& operator[](int pos) const { return m_name[pos]; }; char& operator[](int pos) { return const_cast<char&>(static_cast<const Test&>(*this)[pos]); }; private: string m_name; };注:上述代码里有两次转型操作。第一次为*this加上const,调用const operator[]。第二次是将 operator[]返回值的const移除。这样的调用避免了代码的重复。另外一种避免代码重复的方法是:将公共代码移至另外一个 private成员函数里,供函数调用。
总结:
- const可用于任何作用域内的对象、函数参数、函数返回类型、成员函数本身,声明为const可帮助编译器侦测出错误用法。
- 编译器强制实施bitwise constness ,但编写程序时应该使用”概念上的常量性”(conceptual constness);
- 当const和non-const成员函数实质上等价时,令non-const版本调用const版本可避免代码重复。