const
const的引用
我们把对常量的引用称为常量引用(常量指针指是指针指向的对象不变)
一般来说 引用类型必须和引用对象的类型相同 但是也存在意外 常量引用可以初始化为任意表达式作为初始值,只要该表达式可以转换为引用的类型即可
例如:
int i=4;
const int &r2=i; // 合法
double f;
const int &ri=f;
相当于:
const int temp=f;
const int &ri=temp;
ri绑定在了一个临时量上面 所欲这里要求ri必须是个常量 否则ri改变引用对象的值时 只能改变临时量的值 这样时没用的 编译器会报错
顶层const和底层const
顶层const指指针本身是常量,底层指针指指针指向的对象是常量
在执行拷贝时,拷贝的对象必须要有相同的底层指针,或者类型能够转换
例如:
const int* const p1; //注意前面是底层 后面是底层
int* p2;
p2=p1; // 报错 p1底层为const inti* p2底层为int
constexpr和常量表达式
常量表达式指值不会改变并且编译器在编译时就能计算其结果的表达式 字面值属于常量表达式 用常量表达式初始化的const对象也是常量表达式 常量表达式由变量类型以及初始化表达式共同决定
例如:
int i=5; //不是
int j=i*2; //不是
const int k=i*j; //不是
const int c=get_size(); //不是常量表达式
const int a=3; //是
const int b=a+3; //是
constexpr变量(相当与const+类型检查)
实际上在一个复杂的程序中,我们很难看出一个初始值是不是常量表达式 C++11标准规定 允许将变量声明为constexpr类型 编译器会在编译时检查变量是否为常量表达式 不是则报错
例如:
constexpr int i=5; //正确
constexpr int j=i+3; //正确
constexpr int k=get_size(); //报错
字面值类型
常量表达式的值需要在编译的时候就进行计算 因此对constexpr声明时用到的类型必须有所限制 我们把这些类型叫做字面值类型 例如算数类型,引用,指针。类,IO库,string类型则不是字面值类型
尽管指针和引用都能定义为constexpr类型,但是对他们的初始化值有严格的要求,必须nulltrp或0,或是储存在某个固定地址中的对象,定义于所有函数体之外的对象其地址固定不变,能用来初始化constexor指针。
例如:
const int *p=nullptr;
constexpr int *q=nullptr; //constexpr把q设置为顶层const
constexpr int i=5; //constexptr把i设置为const
顶层指针作用于对象本身, 执行拷贝操作时会自动忽略掉顶层指针
const int ci=42;
int i=ci;
int * const p=&i;
在确定函数的形参时,尽量使用常量引用,这表明函数不能改变传入的实参的值,且我们可是传入底层const的引用
推荐阅读
-
const
-
const
-
Effective C++ item01 尽量以const enum inline替换#define
-
《Effective C++》Item2:尽量以const、enum、inline代替#define
-
用const、enum、inline替代#define
-
static vs const vs define
-
条款 02:尽量以 const, enum, inline 替换 #define
-
宏定义(#define)和常量(const)的区别
-
C++宏定义 #define 和常量 const 的区别
-
条款02:尽量以const, enum, inline替换 #define