网站首页 > 技术文章 正文
const 是 constant 的缩写,本意是不变的,不易改变的意思。在 C++ 中用来修饰内置类型变量、自定义对象、成员函数、返回值、函数参数。
1. 修饰普通类型的变量
对于基本的数据类型,修饰符 cosnt 可以在类型说明符前,也可以用在类型说明符后面,其结果是一样的。
const int a = 5;
int const b = 5;
const int arr1[3] = {1,2,3};
int const arr2[3] = {1,2,3};
来看一些对 const 变量的操作:
const int a = 10;
a = 11; // 错误:不能为 const 变量赋新值
int &b = a; // 错误:不能为 cosnt 变量绑定 non-const 引用
const int &c = a; // 正确
int *d = &a; // 错误:不能为 const 变量绑定指向 non-const 的指针
const int *e = &a; // 正确
const 与 define 宏定义的区别:
- 处理阶段不同:define 是在预处理阶段,define 常量不会被编译器看到,因为在预处理阶段已经替换了;const 常量在编译阶段使用。
- 类型和安全检查不同:define 没有类型,不做检查,仅仅是字符替换;const常量有明确的类型,在编译阶段进行类型检查;
- 存储方式不同:define 是字符替换,有多少地方使用,就会替换多少次,不会分配内存;编译器通常不会为 const 常量分配空间,只是将它们保存在符号表内,使它们成为一个编译期间的常量,没有读取内存的操作,效率也很高。
2. 修饰指针变量
const 修饰指针变量有三种情况:
2.1 const 修饰指针指向的内容,则内容为不可变量
const int *p = 8;
const 修饰指针内容,即 *p 的值不可变,只能为8。因为 const 位于 * 的左边,称为左定值。
2.2 const 修饰指针,则指针为不可变量
int a = 8;
int* const p = &a;
*p = 9; // 正确
int b = 7;
p = &b; // 错误
对于 const 指针 p 其指向的内存地址不能改变,但其内容可以改变,称为右定向,因为 cosnt 位于 * 右边。
2.3 cosnt 修饰指针和指针指向的内容,则指针和指针指向的内容都为不可变量
int a = 8;
const int* const p = &a;
这时 p 指向的内容和指向内容地址都已固定,不可改变。
3. 修饰函数参数和返回值
3.1 修饰函数参数
- 值传递的 cosnt 修饰:一般这种情况不需要const修饰,因为函数会自动产生临时变量复制实参值;
- const 修饰指针参数:防止指针被修改;
- cosnt 修饰引用参数:为了增加效率(因为参数为引用不会创建副本)的同时防止被修改,对一般的 int、double 等内置类型,不采用引用的传递方式。
3.2 修饰函数返回值
- 修饰内置类型的返回值,这种情况实际无意义,因为参数返回本身就是赋值。
- 修饰自定义类型的返回值,此时返回的值不能作为左值使用,既不能被赋值,也不能被修改。
- 修饰指针或引用的返回值,保证指针指向内容不被改变。
4. 修饰类的成员变量和成员函数
4.1 类的成员变量
const 修饰类的成员变量,表示该成员为常量,不能不修改,只能在初始化列表中赋值。
class A
{
…
const int nValue; //成员常量不能被修改
…
A(int x): nValue(x) { } ; //只能在初始化列表中赋值
}
4.2 类的成员函数
const 修饰类的成员函数,表示该成员函数不能修改类中的任何非 const 成员变量,一般 const 写在函数的后面,比如 void func() const;。
如果有个成员函数想修改对象中的某一个成员变量,可以使用 mutable 关键字修饰这个成员变量:
#include<iostream>
using namespace std;
class Test
{
public:
Test(int _m,int _t):_cm(_m),_ct(_t){}
void Kf()const
{
++_cm; // 错误
++_ct; // 正确
}
private:
int _cm;
mutable int _ct;
};
int main(void)
{
Test t(8,7);
return 0;
}
- 上一篇: C++中explicit关键字的含义
- 下一篇: C++基础知识点总结
猜你喜欢
- 2025-07-23 5个被严重低估的C++标准库:告别重复造轮子,提升开发效率
- 2025-04-27 详解C++三种new操作符
- 2025-04-27 C++引用的深入一步学习,总结有哪些场景?linux C++第11讲
- 2025-04-27 C++ 中的卷积神经网络 (CNN)
- 2025-04-27 谈谈 C++ 的原子操作与并发
- 2025-04-27 指针的迷宫:C/C++程序员的终极挑战
- 2025-04-27 C++11新特性概述,初始化,auto、for、智能指针、哈希表等
- 2025-04-27 C++启蒙之旅--数据类型怎么玩
- 2025-04-27 最新最全linux c/c++服务器后台开发面试题合集
- 2025-04-27 掌握CONST:C/C++代码安全与优化
- 1518℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 596℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 521℃MySQL service启动脚本浅析(r12笔记第59天)
- 489℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 489℃启用MySQL查询缓存(mysql8.0查询缓存)
- 477℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 456℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 454℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)