本文转载自微信公众号“码砖杂工”,作者我不想种田。转载本文请联系码砖手公众号。很多人对const、const_cast、constexpr的用法一头雾水,一头雾水地使用。一般来说,即使你乱用,问题也不是很大,因为如果你犯了一个大错误,它就会崩溃。如果它崩溃了,它会自然得到纠正。但是作为一个有志向的专业程序员,应该是闻之即兴,思之所想。一、constC语言中const的用法先说const,不知道怎么翻译这个东西。C语言中this关键字的用法比较简单,大概有以下几种用法:[1]修改普通变量:变量是只读的,程序运行时不能修改。constinti=100;//iisreadonlyi=200;//compileerror,variableicannotassignable[2]modifiedpointerconstT*p:表示p指向的对象内容不能通过p修改,反之const成员类T的只能通过p函数调用conststructFoo*f=newFoo;f->dataX=100;//compileerrorconstchar*p="abc";p[1]='x';//compileerrorf->nonconst_member_function();///compileerror(later)[3]ModifiedpointerT*constp:表示该指针只能在初始化时设置,之后不能修改。chars1[]="abc";chars2[]="xyz";char*constp=s1;p=s2;//compileerror[4]修改指针constT*constp:表示p指向的对象不能被已修改,并且p的指向无法更改。constchar*constp="abc";p[1]='B';//compileerrorp="xyz";//compileerror[5]修饰函数参数:c语言中的const修饰参数所体现的含义与以上总结:C语言中,const的用法几乎相同,比较简单。C++扩展了const的用法[1]修饰成员变量:const成员变量只能在初始化列表中初始化,在程序运行过程中不能修改;如果是const整型,可以按照C++11标准直接初始化。structFoo{Foo():PI(3.15){}//PIisinitializedbyinitializerlistconstintc=100;//C++11supportconstfloatPI;};[2]修饰成员函数:表示该成员函数为只读函数,不会修改默认参数this如果修改了成??员变量,编译时会报错。classFoo{intm_money;public:intget_money()const//?{returnm_money;}intset_money(intmoney)const//?{m_money=money;//修改this->m_money;需要去掉函数const修饰}};[3]修饰引用:引用是C++特有的语法特征。引用是别名,本质上类似于指针,因此const修饰的引用与修饰的指针具有相似的语义和约束。Foof;constFoo&r=f;r.m_data=1;//compileerror[4]C++中const修饰指针的补充intmain(){constFoo*f=newFoo;f->const_member_function();//OKf->non_const_member_function();//compileERRORreturn0;}为什么?因为const成员函数相当于promise不去修改this的成员变量,并且这个promise会被编译器检查,如果promise没有实现,编译器就会报错。而constFoo*f表示f指针指向的变量的内部值不能通过f修改。肯定不能用f->data=1。另一方面,你只能通过f调用它的const成员函数,因为const成员函数的语义是不会修改this的值,编译器可以很容易地进行这个检查。const修饰参数const可以修饰普通参数,也可以修饰指针/引用参数。因为形参是实参的拷贝,const修饰普通参数是没有意义的。我们将重点关注const修饰的指针/引用参数。例如标准C库函数strcpy的签名:char*strcpy(char*dst,constchar*src);dst代表目标地址,src代表源字符串,const修饰源字符串。这是因为源字符串被复制到目标字符串。无需修改源字符串内容,相当于给strcpy调用者一个承诺:放心大胆调用,strcpy函数的实现保证src内容不被修改,编译器将执行此检查。这样在review代码的时候,如果想跟踪src哪里被修改了,看到strcpy的签名时,就不用打开函数看实现了。只要不违背承诺,绝对不是这个函数里改的src。constchar*src是一个承诺和约束。在调用的地方,constchar*形式的形参既可以传constchar*实参,也可以传char*实参,因为constchar*是一个更强的promise。但反之则不然。比如第一个参数dst不包含const,那么如果有constchar*p的变量类型,那么p就不能作为第一个参数传入strcpy,编译就会失败。因为strcpy不承诺不修改dst,它是一个较弱的承诺。只有声明为const指针的参数才能传递const指针实际参数。const其他的const也可以修饰返回值,也可以和extern结合使用,不过这些都是一些语法小技巧,一般开发中不常用到,遇到了再查也不迟。2、const_castconst_cast有什么用?const是C++的强制转换,用于去除const属性,如:Foofoo;constFoo*f1=&foo;Foo*f2=const_cast
