C++ 到处乱摆的 const 都是什么意思? 用 constexpr 要注意什么?

2023-06-04 0 557

C++ 中的 const 能用以润色任何人的表达式、表达式、操作符表达式等,被它润色的表达式值都难以被发生改变。

const 润色表达式以做为自变量

采用 const 润色的表达式值难以修正,所以须要在新闻稿时就顺利完成调用:

const int var = 5;

假如把新闻稿和调用合二为一,C++就会在校对先驱报错。如上面此种读法是没用的:

const int var; var = 666;

const 润色操作符

const 在操作符新闻稿的最后面

此种读法叫作“用操作符对准两个 const 表达式”

int a = 666; const int* aPtr = &a; int b = 888; aPtr = &b; // ok a = 123; // ok *aPtr = 123; // 不 ok

这样新闻稿出来的操作符,被对准的对象能修正(假如被对准的对象没有 const 的话),也能替换操作符所对准的地址。但不能以解引用的方式来修正操作符所对准的对象。C++会报错:

error: read-only variable is not assignable

const 在新闻稿的中间

此种读法叫作“用 const 操作符表达式对准两个表达式”

这样新闻稿的操作符本身所对准的地址不能发生改变

int a = 666; int* const aPtr = &a; // const 操作符对准非 const 表达式 a = 123; // ok *aPtr = 888; // ok int b = 321; aPtr = &b; // 不 ok

试图重新修正 aPtr 内的地址会导致C++报错

error: cannot assign to variable aPtr with constqualified type int *const

在开始和中间写俩 const

此种读法叫作“用 const 操作符表达式对准两个 const 表达式”

int a = 666; int b = 888; const int* const aPtr = &a; a = 123; // ok *aPtr = 123; // 不 ok aPtr = &b; // 不 ok

const 润色表达式

const 在最开始

通常不须要这么写。比如上面这段代码:

const int foo() { return 3; } int main() { int a = foo; a = 666; // 合法 }

返回值后面的 const 并不会阻止后面对返回值的修正。

(详见:c++ – Purpose of returning by const value? – Stack Overflow

const 在末尾

MyType MyClass::showName(string id) const { }

说明该表达式是该类的两个 const 成员表达式,该表达式不能修正其所在类的任何人成员表达式(除非成员被明确标识为 mutable )。试图在其中修正成员值将导致校对报错。

实际上,这是由于 C++ 的成员表达式都隐含了两个对准自身的 this 操作符参数导致的。实际的该表达式类似于上面这样:

MyType MyClass::showName(MyClass *this, string id) const { }

末尾的 const 起到的效果类似于

MyType MyClass::showName(const MyClass *this, string id) { }

this 变成了 const 类型。因此也就不能修正自身值了

const 润色参数

被 const 润色的表达式参数难以在表达式内被修正:

void foo(const int param) { // 不能修正 param 的值}

const 引用:

void printReference (const string& str) { cout << str; } void printReference (string&& str) { cout << str; }

第两个表达式能够接收左值,因为参数表中写的是左值引用。同时也能接收右值,因为参数是 const 的,而右值是能绑定到 const 的左值引用的。

第二个表达式只能接收非 const 的右值,因为难以从引用中隐式地删除 const

constexpr

const 润色的表达式只有在程序运行时才会被调用并动态绑定的。若要在校对时静态绑定自变量值,能采用 constexpr

C++ 中推荐的常量定义方式:

constexpr int RECVID = 12;

constexpr 的出现,能让C++在校对时对这句话做三件事:

可能会将该值在其被采用的地方内联;若在作用域内出现重名,C++能报错;能在校对时保证类型安全

应采用 const 而不是 constexpr 的情况

有些不可表达式的值须要在运行时才能确定,文件描述符就是两个典型的例子:

const int fd = GetFileDescriptor(“file.txt”);

因为显然,文件描述符不是两个校对时就能确定的值。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务