C++ const 记录

C++ 中的 const

先来了解以下什么是const。

一、const 介绍

const 用来定义一种变量,它的值不能改变,随时警惕防止程序一不小心改变了这个值。因为const对象一旦创建后,它的值不能改变,所以const对象必须初始化。

例子:

const int i = 42;

默认状态下,const对象仅在文件内有效。 当多个文件中出现了同名的const变量,其实等于在不同文件中分别定义了独立的变量。 如果想某些时候确实想多个文件共享这么一个const变量,需要对于const变量不管是声明还是定义都添加extern关键字,这样只需定义一次就可以了。

例子:

//在一个文件内定义并且初始化了一个常量,
//该常量能被其他文件访问
extern const int bufSize = 100;

//其他文件
extern const int bufSize;

1. Const的引用

对常量的引用,与普通的引用不一样,对常量的引用不能被用作修改它们所绑定的对象。
例子:

const int ci=1024;
const int &r1 = ci; //正确
r1 = 42; //错误
int &r2 = ci;//错误

2.指针和const

(1)指向常量的指针

要想存放常量对象的地址,只能使用指向常量的指针,但是指向常量的指针不能用于改变其所指向对象的值,且指针的类型必须与其所指对象的类型一致。
例子:

const double pi = 3.14;
double *ptr = π //错误
const double *cptr = π//正确
*cptr = 42;//错误

(2) const 指针

常量指针必须初始化,而且初始化后,它的值(也就是存放在指针的地址)就不能改变。
例子:

int errNumb = 0;
int *const curErr = &errNumb; //curErr將一直指向errNumb
const double pi = 3.14;
const double *const pip = π //pip是一个指向常量对象的常量指针

*pip = 2.72; //错误,pip是一个指向常量的指针
*curErr = 0; //正确,把curErr所指的对象的值重置

总结一下就是: 如果关键字const出现在号左边,表示被指物是常量;如果出现在号右边,表示指针自身是常量;如果出现在*号两边,表示被指物和指针两者都是常量。

(3) const_iterator

迭代器的作用就像个指针。声明迭代器为const就像声明指针为const一样,表示这个迭代器不得指向不同的东西,但它所指的东西可以改变。
例子:

std::vector<int> vec;

const std::vector<int>::iterator iter = vec.begin(); //iter像const 指针
*iter = 10; //正确,改变iter所指物
++iter; //错误,不能改变所指的东西

std::vector<int>::const_iterator cIter = vec.begin(); //cIter像指向常量的指针
*cIter = 10; //错误
++cIter; //正确

3. const 形参和实参

当用实参初始化形参时候,会忽略顶层const。换句话说,形参的顶层const被忽略了。当形参有const时候,传给它常量对象或者非常量对象都是可以的。
例子:

void fcn(const int i) {/*fcn 能够读取i,但是不能向i写值 */}

void fcn(int i) {/*       */} //错误:重复定义了fcn(int)

c++中,可以定义两个相同名字的函数(fcn),但是前提是不同函数的形参列表应该有明显的区别。因为顶层的const被忽略了,所以在上面的代码中传入两个fcn函数的参数可以完全一样。因此第二个fcn错误的,尽管形式上有差异,但是形参一样的。

4.常量引用

尽量使用常量引用。把函数不会改变的形参定义成普通的引用是一种比较常见的错误,这么做带给函数的调用者一种误导,即函数可以修改它的实参的值。此外,使用引用而非常量引用也会极大地限制函数所能接受的实参类型。
例子:

string::size_type ctr = 0;
string::size_type find_char(string &s, char c, string::size_type &occurs);
//只能將find_char函数作用于string对象。
find_char("hello world", "o", ctr); //错误

find_char(s, ".", ctr); //如果const string &s,错误。

所以除非有需要改动参数或者local对象,否则请將形参声明为const。

上一篇:Android中启动JAVA程序


下一篇:Java实现 LeetCode 352 将数据流变为多个不相交区间