Cpp pro tip 尽可能使用const

如果某个值需要保持不变,那么你就应该说出来,这样编译器能确保这写约束不被违反。const可以放于很多位置。

1. 作用于指针

1
2
3
4
5
char greeting[] = "hello";
char* p = greeting;
const char* p = greeting; // 1
char* const p = greeting; // 2
const char* const p = greeting; // 3

const的出现位置[左数右针]:

  1. const *数据是常量,表示被指向的对象是常量,而指针是可以变的。
  2. * const,表示指针是常量这个指针不能指向不同的东西,但它指向东西的数据可以改变
  3. const * const,表示指针和被指向的对象都是常量

对于在*左侧,下面两种表达意义相同,都在左侧:

1
2
const char* greeting;
char const* greeting;

2. 作用于特殊指针,iterator

对于STL中的迭代器,加入我希望迭代器所指向的东西不可被修改(即对数据只读),那么就需要一个const_iterator

1
2
3
4
5
vector<int> vec;
// 数据const
vector<int>::const_iterator cItr = vec.begain();
*cItr = 10; // 错,所指向的东西不能改
cItr++; // 对,指针可改

而另一种情况,指针不能改变其指向,但是可改变其所指向数据:

1
2
3
4
// 指针const
const vector<int>::iterator itr = vec.begain();
*itr = 10; // 对,所指向的东西可改
itr++; // 错,指针指向不可改

3. 作用与函数

  1. 函数返回值为const

    将函数返回值声明为const,这个返回值不能被修改。降低了因为用户的错误而造成的意外。

  2. 函数参数为const

    除非你要改动局部变量(函数参数),否则将参数声明为const。

4. 作用与类成员函数

即const位于成员函数()和{}之间,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
class foo {
public:
inline void area(int x, int y) {
length_ = x;
width_ = y;
}
// length和width,不能被这个函数修改。
// 限制对象成员函数 改变对象数据成员,保护了程序的健壮性和稳定性
void print() const {cout<<"area="<<length_ * width_<<endl;}
private:
int length_;
int width_;
};

print()成员函数,为const函数,表示这个成员函数不能修改成员变量。所以不能将area()成员函数设为const,因为这个函数的 目的就是为成员变量赋值。

const成员函数,和非const成员函数使得我们知道一个类中哪些函数可以修改成员属性,哪些不可以

tip:
提升c++程序效率的一个方法是以pass by referrence-to-const的方式或pass by pointer-to-const传递对象:

1
2
// 此为以成员函数
const int opt( const foo& x) const { return x.length_ * x.width_}