const 用语
const第一类要调用。const第一类除非建立无法修正。const int bufSize = 512;
通常const表达式只在现阶段文档内能采用。extern能让数个文档相连接两个const表达式,因此防止多次重复表述。// file_1.cc
// 表述并调用两个自表达式,那个自表达式能被其它文档出访。
extern const int bufSize = fcn();
// file_2.h
// 与file_1.h中的bufSize是同两个。extern const int bufSize;
对自表达式的提及明确要求提及要要用自表达式提及,通常用在表达式表述的这时候。// 自表达式提及的表述
const int& a = 1;
// 不须要这种表述,提及原本是不容发生改变的。int const & a = 1;
// 当Apple是两个非常大的第一类时,他们能既不该fork,又不该发生改变它的这时候就能用自表达式提及实参。
Apple fun(const Apple& a){
}
const Apple a;
Apple b;
// 对ab的调用都是能的。
fun(a);
fun(b);
// 但是
Apple fun(Apple& a){
}
// 无法调用fun(a);
// 他们在写表达式的这时候就应该想好,会不会对参数就行修正。// 如果要修正,那么就取第二种表达式表述,传入自表达式第一类是错误的行为。
// 如果不修正,那么就取第一种表述,传入自表达式和非自表达式第一类都是能编译通过的。
自表达式提及能用能用任何表达式调用,通常提及无法绑定临时量。void fun(Apple& a){
return;
}
Banana b;
fun(b);
// Banana类型能转换成Apple,转换后是两个临时表达式,无法被fun调用,编译会出错。// 添加两个表达式重载就能编译通过。
void fun(const Apple& a){
return;
}
自表达式指针和指向自表达式的指针。// 指针指向的表达式不容变
const double *a = nullptr;
// 指针不容变
double const *a = nullptr;
// 前者常用于表达式的输入表达式。
顶层const表示指针本身是两个自表达式。底层const表示指针所指第一类是两个自表达式。
顶层const指针必须跟通常表达式一样调用,而底层const指针不用。
自表达式第一类能赋值给非自表达式第一类,反之则不行。此过程有隐式类型转换。const第一类不必采用自表达式表达式调用,而constexpr要用自表达式表达式调用,借此编译器能检查编译期间是否能计算表达式的值。constexpr int a = 0;
字面值类型的表达式才能用于调用constexpr第一类。p59constexpr把第一类设置成顶层const。能用const_cast去掉const性质,但是即使去掉const性质了,他们也不应该修正它。const char* pc;
char *p = const_cast<char*>(pc);
// 也能加上const
const char* pcc = const_cast<const char*>(p);
对于表达式重载,顶层const不影响传入表达式的第一类,因为实参传入后调用为新的参数。对于表达式重载,底层const会限制传入第一类。void fun(const int* data); //只能传入底层const
void fun(int* data); //能传入底层const或非底层const,编译器会根据规则优先匹配
const_cast能让非底层const第一类传入底层const实参。void fun(int* data){
fun(const_cast<const int*>(data))
}
const动态第一类能隐式调用。p408将参数设置成常提及能接收的参数种类明显更多。自表达式指针就不一样。两个表达式的参数如果是const int*,那么只能传入const int*类型的参数,int*不会升级成const int*,将它传入那个表达式就会出错。他们能重载两个表达式强制加上const属性,这样就能调用了。
总结:
如果表达式不发生改变被提及的第一类,那么表达式的参数表述为const Apple&。
int fun(const Apple& a){
return 0;
}
如果表达式不发生改变指针指向的第一类,那么表述两个表达式:
int fun(const Apple* a){
return 0;
}
int fun(Apple* a){
return fun(const_cast<const Apple*>(a));
}
constexpr的用语见