const形参和实参

  当形参是const时,必须要注意关于顶层const的讨论。如前所述,顶层const作用于对象本身:

  const int ci = 42;  //不能改变ci,const是顶层的
  int i = ci;         //正确,当拷贝ci时,忽略了它的顶层const
  int *const p = &i;  //const是顶层的,不能给p赋值
  *p = 0;             //正确:通过p改变对象的内容是允许的,现在i变成了0
知识兔

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

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

  调用fcn函数时,既可以传入const int也可以传入int。忽略掉形参的顶层const可能产生意想不到的效果。

void fcn(const int i) {} //fcn能读取i,但是不能向i写值
void fcn(int i) {}       //错误:重复定义了fcn(int)
知识兔

  在C++语言中,允许我们定义若干具有相同名字的函数,不过前提是不同函数的形参列表应该有明显的区别。因为顶层const被忽略掉了,所以在上面的代码中传入两个fcn函数的参数可以完全一样。因此第二个fcn是错误的,尽管形式上有差异,但实际上它的形参和第一个fcn的形参没有什么不同。

指针或引用形参与const

  形参的初始化方式和变量的初始化方式是一样的,所以回顾通用的初始化规则有助于理解本节知识。我们可以使用非常量初始化一个底层const对象,但是反过来不行;同时一个普通引用必须用同类型的对象初始化。

int i = 42;
    const int *cp = &i; //正确:但是cp不能改变i
    const int &r = i;   //正确,但是r不能改变i
    const int &r2 = 42; //正确
    int *p = cp;        //错误:p的类型和cp的类型不匹配
    int &r3 = r;        //错误:r3的类型与r的类型不匹配
    int &r4 = 42;       //错误:不能用字面值初始化一个非常量引用
知识兔
计算机