const关键字 墨蓝 2023-11-11 06:46 65阅读 0赞 一、const修饰变量 1、const修饰的常量必须初始化 2、const修饰的常量不可改变其值 3、对于常量,编译器会将其放在一个只读的内存区域,其值不能发生改变。 4、使用常量的好处就在于灵活,程序中多次用到常量,修改其值时,只需要改变定义时候的常量值就可以。 若非要改变: #include <stdio.h> int main() { const int a = 10; int *p =(int *) &a; (*p)++; printf("%d\n", a); return 0; } 二、const修饰函数 1、在类中将成员函数修饰为const表明在该函数体内,**不能修改对象的数据成员而且不能调用非const函数**。为什么不能调用非const函数?因为非const函数可能修改数据成员,const成员函数是不能修改数据成员的,所以在const成员函数内只能调用const函数。 2、const修饰函数参数 防止传入的参数代表的内容在函数体内被改变,但仅对指针和引用有意义。因为如果是按值传递,传给参数的仅仅是实参的副本,即使在函数体内改变了形参,实参也不会得到影响。如: void fun(const int i)\{ i = 10; \} 在函数体内是不能改变i的值的,但是没有任何实际意义。 const修饰的函数参数是指针时,代表在函数体内不能修改该指针所指的内容,起到保护作用,在字符串复制的函数中保证不修改源字符串的情况下,实现字符串的复制。 void fun(const char \* src, char \* des)\{ //保护源字符串不被修改,若修改src则编译出错。 strcpy(des,src); \} void main()\{ char a\[10\]="china"; char b\[20\]; fun(a,b); cout<<b<<endl; \} 而且const指针可以接收非const和const指针,而非const指针只能接收非const指针。 const修饰引用时:如果函数参数为用户自定义的类对象如: void h(A a)\{ ………… ………… \} 传递进来的参数a是实参对象的副本,要调用构造函数来构造这个副本,而且函数结束后要调用析构函数来释放这个副本,在空间和时间上都造成了浪费,所以函数参数为类对象的情况,推荐用引用。但按引用传递,造成了安全隐患,通过函数参数的引用可以修改实参的内部数据成员,所以用const来保护实参。 void h(const A & a)\{ ………… ………… \} 3、const修饰函数的返回值 (1)函数返回const指针,表示该指针不能被改动,只能把该指针赋给const修饰的同类型指针变量。 (2)函数返回值为值传递,函数会把返回值赋给外部临时变量,用const无意义!不管是内部还是非内部数据类型。 (3)函数采用引用方式返回的场合不多,只出现在类的赋值函数中,目的是为了实现链式表达。 三、指针常量与常量指针 const int *p //p可变,但是p指向的内容不可变 int const * p //p可变,但是p指向的内容不可变 int * const p //p不可变,p指向的对象可变 const int *const p //指针p和p指向的对象都不可变 四、const修饰左值引用 `const` 修饰左值引用类型时(`const Type &`),作用有两个: * 不能通过该引用变量修改被引用的对象; * 该引用变量既可引用一个左值,也可引用一个右值(字面值或临时对象)。 所以,当 `const` 修饰函数形参中的左值引用时,表示该形参既可接受一个左值亦可接受一个右值。 #include <string> #include <iostream> void printStringL(std::string &str) { std::cout << str << std::endl; } void printStringLR(const std::string &str) { std::cout << str << std::endl; } int main() { printStringL("hello world!"); // error printStrinfgLR("hello world!"); // ok return 0; } 运行上面程序,会发现编译错误,看完下面,应该就能理解为什么了。 const在函数形参中的第一个作用想必很多人都知道,就是为了设置被修饰的变量为只读状态(即不允许被修改)。但是应该有挺多人忽略了其第二个作用。 其第二作用就如同上面例子中的 printStringLR 函数,当const 修饰一个左值引用(型如const Type &)时,表示该左值引用既可以引用一个左值,也可以引用一个右值(字面值或临时对象),而不带 const修饰的左值引用(型如Type &)只能引用一个左值,不能引用一个右值。 所以,当 const 修饰函数形参中的左值引用类型时,表示该左值引用既可以引用一个左值,也可以引用一个右值,如printStringLR函数;而没加const的左值引用形参,只能接受一个左值,如 printStringL函数。 注:将 “hello world!” 传递给 printStringL和printStringLR函数,会构造出一个临时的 string对象。 五、const和\#define的区别 #define a 10 const int b=10; //a表示的是常量 int arr[a]={}; //b表示的是常量 int brr[b]={}; (const和#define 都可以表示常量) 不同之处在于: a. 宏定义: 由预处理处理,单纯的是纯文本替换。 b. const常量: 由C++编译器处理,提供类型检查和作用域检查。 #define a 10 void print() { //表示宏定义无作用域检查, cout << a << endl; //这个语句不合法,表示的是const具有作用域检查 //cout << b << endl; } int main() { const int b = 10; //typedef不能用于a,表示的是a无类型只是单纯的文本替换 //const变量具有类型 return 0; }
还没有评论,来说两句吧...