C++_04_const用法
const定义常量
const是C++用来增加数据安全性,并且限制数据共享,保证数据不会被任意修改的机制。
被const修饰的变量,其值在运行期间不能改变,即一经赋值不能再重新赋值,可以称为常变量
切忌:定义任意类型的常变量必须同时对其进行初始化赋值,此后其值不能再改变(被赋值)
const修饰普通变量和指针
const修饰普通变量时要初始化赋值
#include<iostream> using namespace std; /* const修饰常量 ---修饰成员变量时,必须在构造函数的参数列表中初始化 ---修饰成员函数时,加在函数后面,并且该函数无法修改成员属性 */
//const修饰普通变量时要初始化赋值
int main(int argc, char const *argv[]) { int x = 1; const int a = 10; int const b = 20; //定义两个整形常量,以上两种写法作用一致,没有区别(const和int谁前谁后无所谓) const int *c = &a; //const修饰指针指向的值为常整形, //指针的地址可以修改,但锁指向的数据不能修改 int * const d = &x; //const修饰的是指针本身,为常指针 //即指针变量(地址)不能修改,但是指针指向的数据可以修改 const int * const e = &a; //const同时修饰指针和指针指向的数据,两针皆不可修改
//前后主要看是在(*)前还是(*)后 cout << "-------------------初值---------------------" << endl; cout << "x = " << x << " " << "&x = " << &x << endl; cout << "a = " << a << " " << "&a = " << &a << endl; cout << "b = " << b << " " << "&b = " << &b << endl; cout << "c = " << c << " (a的地址)" << " *c = " << *c << endl; cout << "d = " << d << " (x的地址)" << " *d = " << *d << endl; cout << "e = " << e << " (a的地址)" << " *e = " << *e << endl; // a = 200; // b = 300; int m = 80; c = &m; /* *c = 400; */ // d = &m; *d = 500; // e = &m; /* *e = 600; */ cout << "-------------------赋值---------------------" << endl; cout << "x = " << x << " " << "&x = " << &x << endl; cout << "a = " << a << " " << "&a = " << &a << endl; cout << "b = " << b << " " << "&b = " << &b << endl; cout << "c = " << c << " (a的地址)" << " *c = " << *c << endl; cout << "d = " << d << " (x的地址)" << " *d = " << *d << endl; cout << "e = " << e << " (a的地址)" << " *e = " << *e << endl; return 0; }
const修饰成员变量
在C++类中的成员变量,只能使用初始化参数列表进行初始化赋值
成员变量的初始化顺序只与成员变量在类中声明的顺序有关
例如:先有m_a,再有m_b,那么初始化时候,先赋值m_a后m_b
#include <iostream> using namespace std; class Demo{ private: int a; char b; public: Demo(); //构造函数声明 void show(); }; Demo::Demo():a(6),b('e') //构造函数定义,参数列表初始化 {
} void Demo::show(){ cout<<a<<", "<<b<<endl; } int main(){ Demo obj; obj.show(); return 0; }
const修饰成员函数
1、const成员函数可以访问const和非const成员变量,但是不能修改任何成员变量的值
2、非const成员函数不能访问const成员变量,只能访问和修改非const成员变量
3、const 成员函数是不能调用类中非 const 成员函数的。(const成员函数在只能调用const成员函数)
const成员函数一般类中声明,类外定义,当然也可以类中声明定义
返回值类型 成员函数名(参数列表) const
//注意:const修饰成员函数,放置函数名后面,函数声明和定义的时候都要加const { 函数体; }
//对于成员函数而言,const放在成员函数前,是限制函数返回类型为指针时通过指针对返回值的修改,
//非指针的函数返回类型前加const是没有意义的
//const放在成员函数后,是限制类的成员函数不能对成员变量进行修改
const修饰类对象
在C++中const可以用来修饰对象,称为常对象。
(const常对象只能调用const成员变量或成员函数)
语法格式: const 类名 对象名(实参表列) //方式1 类名 const 对象名(实参表列) //方式2
const 类名 *指针名 = new 类名(实参表列); //指向常对象的指针法1 类名 const *指针名 = new 类名(实参表列); //指向常对象的指针法2 //以上同样是定义常对象的方法,对象不可变,指针可变 //以下是定义指向对象的长指针的方法,指针内存放不可变,对象可变 类名 *const 指针名 = 对象地址 //指向对象的常指针
上面的案例已经介绍过const修饰成员变量的场景了吗,这里就不再过多描述!!!
const常对象只能调用const型成员变量或成员函数,不能调用非const型成员变量或成员函数;
这是为了防止调用的成员变量或成员函数对常对象进行修改。
const常引用
格式; const 类名 &引用名 = 对象名
1、常引用只能调用常成员函数;
2、常引用作为函数形参时,函数中不能有修改其对应实参的语句;
3、常引用作为函数形参时,实参可以是一般对象、常对象、一般引用、常引用;
4、一般引用作为函数形参时,实参只能是一般对象或一般引用。
const在C语言和C++中的比较:
在C中const是“冒牌货”
在C中 const int a = 10;
不是真的说a被定义为一个常量(冒牌货),a依旧可以通过指针修改其数据值
C语言中const变量是只读变量,有自己的存储空间
在C++中 const int a = 10;
const
定义的才是常量,不可修改。
可能分配存储空间,也可能不分配存储空间
(C++中编译器将const修饰的变量放置在符号表中,在这个表中,不论是变量名、地址、数据本身都是不允许被改变的——就是完完全全的常量,当需要去地址的时候,会单独再分配一块空间,用指针存取(拷贝)变量的地址,这个地址对应的新空间数据和原来的数据没有一点点关系,不会影响到原来的数据值,如下图:)
当const常量为全局,并且需要在其它文件中使用或者当使用&操作符取const常量的地址的时候,才分配内存空间,但也只是取地址,依旧不能修改内存中存放的2数据本身
当使用&操作符,取const常量的地址时,会分配存储空间
当const int &a = 10; const修饰引用时,也会分配存储空间
正因为单独给const常量分配内存,导致有机会通过地址修改数据值,这样和常量初衷矛盾(C语言);
正常情况下,C语言const会分配单独内存空间,但C++一般不会首先这样做。当C++需要分配内存空间的时候(编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间),也只能通过&获取地址,但不能更改存储空间的数据本身
const和#define比较
const和#define相同之处
C++中的const常量类似于宏定义 const int c = 5; ≈ #define c 5
const和#define的区别之处
const常量是由编译器处理的(编译期间),提供类型检查和作用域检查,const常量分配内存
宏定义由预处理器处理(编译预处理期间),单纯的文本替换,故,宏定义不会重新分配内存
在c语言中
1、const修饰全局变量num 变量名只读 内存空间在文字常量区(只读)、不能通过num的地址 修改空间内容
2、const修饰局部变量data 变量名只读 内存空间栈区(可读可写),可以通过data地址 间接的修改空间内容
#include<stdio.h> const int b =200; //全局变量,存储在文字常量区 void main() { const int a = 100; //局部变量,存储在栈区 printf("a = %d\n",a); printf("b = %d\n",b); //a = 2000; //err //b = 2000; //err printf("a1 = %d\n", a); printf("b1 = %d\n", b); int* pa = &a; *pa = 5000; //局部变量 int* pb = &b; //*pb = 5000; printf("a2 = %d\n", a); printf("b2 = %d\n", b); }
C++中
1、const修饰全局变量内存空间在文字常量区(只读)、不能通过num的地址 修改空间内容
2、const修饰局部变量内存空间栈区(可读可写),可以通过data地址 间接的修改空间内容,但是修改的不是你想要改的数据,只不过被修改的是临时拉过来的群演,替身。
1、const int data = 10;//data先放入符号表
2、如果对data取地址 系统才会给data开辟空间
3、const int a = b;//b是变量名 系统直接给a开辟空间 而不放入符号表
4、cosnt 修饰自定义数据 系统为自定义数据开辟空间
#include<iostream> using namespace std; const int a = 200; void main() { cout << "全局变量a = "<<a << endl; //a = 2000; //err //int* q = (int *)&a; //*q = 3000; cout << "全局变量a1 = " << a << endl; //cout << "全局变量a1 = " << *q << endl; const int b = 1000; cout << "局部变量b = " << b << endl; //b = 2000; int* p = (int *) & b; *p = 3000; cout << "局部变量b1 = " << b << endl; cout << "局部变量*p = " << *p << endl; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!