第五版C++primer 中有几个解答比较令人疑惑。
首先:关于引用:
引用的类型必须和与之绑定的对象严格匹配,两种情况除外:
1、初始化常量引用的时候,允许任意表达式作为初始值,只要该表达式能转化成引用的类型即可;
2、存在继承的类:可以将基类的指针或者引用绑定到派生的类上;
主要分为三种量:非常量,顶层const,底层const;
1、底层const对拷贝操作有限制,顶层const对拷贝操作没有限制;
2、非常量可以给顶层const和底层const赋值;
3、顶层const与非常量之间,只要不直接改变顶层const的值,非常量与顶层const可以看做同一类型;
// 讲解部分
int i=0;
int *cosnst p1=&i; //顶层const,非常量给顶层const赋值;
const int ci=42; //顶层const,
const int *p2=&ci; //底层const, 实际上*pi类型和ci类型一致
const int *const p3=p2; //左边底层const抵消,右边顶层const,实际上是非常量
// p2转化为常量p3
const int &r=ci; //底层const,顶层const量ci转化为底层const &r
i=ci; //顶层const给非常量赋值
p2=p3; //都是底层const,顶层const量p3给非常量p2赋值;
int *p=p3; //错误,没有底层const
p2=&i; //正确,因为p2实际上是非常量,*p2才是常量;
int &r=ci; //错误,除了两种情况,引用类型必须与绑定值类型匹配
const int &r2=i; //正确,非常量给底层const赋值;
//练习部分
const int V2=0; //顶层const;
int v1=v2; //顶层const给非常量赋值;
int p1=&v1; //
int &r1=v1; //
const int *p2=&v2 //顶层const给底层const赋值;
const int *const p3=&i //非常量给有顶层const和底层const的量赋值;
const int &r2=v2; //顶层const赋值给底层const;
r1=v2; //正确,顶层const赋值给非常量;
p1=p2; //错误,底层const 不能给非常量赋值;
p2=p1; //非常量赋值给底层const
p1=p3; //错误,底层const 限制;
p2=p3; //底层const抵消掉,顶层const给非常量赋值;
小练习:
#include<iostream>
using namespace std;
const int *p1 = 0;
void main()
{
const int ci = 42; //变量ci的地址指向42,变量ci与地址绑定,地址与42绑定
const int *p2 = &ci; //变量p2与ci的地址绑定
const int *const p3 = p2; //p3与ci的地址绑定;
int ck = 0;
p2 = &ck; //p2与ck的地址绑定;
cout << &ci << endl;
cout << p2<<" "<< p3<<endl;
cout << *p2 << " " << *p3<< endl;
}
输出为:
005EF764
005EF740 005EF764
0 42