函数重载与const形参

1. 顶层const(top-level const)与底层const(low-level const)为了更好的研究指针和引用,我们引入了底层const这个名词。注意,底层const是针对C++里面的指针和引用而引入的。我们知道,指针本身是不是常量与该指针所指向的是不是常量,这是两个相互独立的问题。为了区分这两种情况,我们引入两个专有名词:顶层const(top-level const)与底层const(low-level const)。用 顶层const(top-level const)表示指针本身是一个常量,而用 底层const(low-level const)表示指针所指的对象是一个常量。由指针引入,更一般的,顶层const可以表示任意的对象(任何数据类型)是常量。而底层const则与指针和引用等复合类型的基本类型部分有关。为了检验一下有没有正确理解什么是顶层const(top-level const)与底层const(low-level const),请看几个小例子:int i = 0;int *const p1 = &i;//不能改变p1的值,因为p1是一个顶层constconst int ci = 1;//不能改变ci的值,因为ci是一个顶层constconst int *p2 = &ci;<span style="white-space:pre"></span>//允许改变p2的值,因为p2是一个底层constconst int * const p3 = p2;<span style="white-space:pre"></span>//靠左的是底层const,靠右的const是顶层constconst int &r = ci;//用于声明引用的const都是底层const,因为引用本身就是一个顶层const,只能在初始化的时候进行赋值对于拷贝操作,顶层const没有什么要求,而底层const要求左值必须比右值更严格。拷贝操作时,对于顶层const,可以把一个顶层const值赋给一个非顶层const变量,也可以把一个非顶层const值初始化给一个顶层const值。如上面例子中:int *const p1 = &i;//把一个非顶层const值初始化给一个顶层const值i = ci;//变量ci是顶层const,但变量i不是顶层constp2 = p3;//变量p3是顶层const,但变量p2不是顶层const拷贝操作时,对于底层const,左值必须和右值相同或更严格。也就是说,对于指针和引用,如果右值是const,则左值必须是底层const。还是上面的例子:int *p = p3;//error:p3包含底层const,而p没有p2 = p3;//正确:p2与p3都是底层constp2 = &i;//正确:int*能转换成const int*int &r = ci;//error:r只具有顶层const而不具有底层const,而ci具有底层constconst int &r2 = i;//正确:可以把普通变量赋给const int&2. const形参与函数重载对于函数调用,和其他初始化过程一样,当用实参初始化形参时,会忽略掉形参的顶层const。这句话的意思也就是说,如果想通过顶层const进行函数重载,是不会通过编译的。函数重载机制会自动假装忽略掉顶层const而保留底层const。也就是说:void func(const int i);void func(int i);编译器认为这是同一个函数,而不是函数重载,进而报错|error: redefinition of ‘void func(int)’|。这个例子告诉我们,一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开来。但是,我们可以通过底层const来进行函数重载。Record lookup(Account&);//函数作用于Account引用Record lookup(const Account&);//新函数,函数作用于常量Account引用Record lookup(Account*);//新函数,函数作用于指向Account的指针Record lookup(const Account*);//新函数,函数作用于指向Account常量的指针当然,当我们传递一个非常量对象或者指向非常量对象的指针时,编译器会优先选用非常量版本的函数。3. 写在最后的题外话(面试常问的问题):对于函数形参中的引用,尽量使用常量引用。首先,如果使用普通引用,会带给调用者一种误导,,即函数可以修改它的实参的值。此外,使用普通引用而非常量引用,也会极大地限制函数所能接受的实参类型。因为我们不能把const对象、字面值或者需要类型转换的对象传递给普通的引用形参。而const引用就可以。

在开始时却总是不厌其烦地渗透入生活的缝隙,

函数重载与const形参

相关文章:

你感兴趣的文章:

标签云: