C++ const 完整语法整理

C++ const 完整语法整理

const 是 C++ 核心的类型限定符,核心作用是给数据 / 函数添加 “只读” 约束,编译阶段强制检查修改行为,既提升代码安全性、可读性,也帮助编译器做优化。以下按「使用场景」拆解const的语法、作用和核心规则,覆盖从基础到类成员的全场景。

一、核心定义

const(常量)本质是 “只读契约”:

  • 编译期检查:禁止修改被const修饰的内容,违规直接报编译错误;
  • 无运行期开销:仅在编译阶段生效,不额外占用内存(除非对const变量取地址 / 声明为全局 / 静态);
  • 核心价值:避免意外篡改数据、明确函数 “只读行为”、支持 const 对象调用。

二、分场景语法详解

场景 1:const 修饰普通变量(全局 / 局部)

语法(两种等价写法)
// 写法1:const 在前(推荐,语义更清晰) const 类型 变量名 = 初始值; // 写法2:const 在后(效果一致,顺序不影响) 类型 const 变量名 = 初始值; 
核心作用

变量一旦初始化,终身不可修改;且const变量必须初始化(否则编译报错)。

示例

 

// 局部const变量(栈上) const double PI = 3.14159; // PI = 3.14; // 错误:只读变量不可赋值 int const num = 10; // 等价于const int num // 全局const变量(全局区,默认作用域为当前文件) const int GLOBAL_NUM = 100; // 跨文件访问全局const:加extern extern const int GLOBAL_NUM2 = 200; 
注意事项
  • 局部const变量:若用字面量初始化(如3.14),编译器可能 “常量折叠”(直接替换值,不访问内存);
  • 全局const变量:默认带static属性(仅当前文件可见),跨文件访问需加extern

场景 2:const 修饰指针(重点!三种核心场景)

核心口诀:左数右指

  • const*左边 → 修饰「指针指向的内容」(数据只读,指针可移动);
  • const*右边 → 修饰「指针本身」(指针地址只读,指向的内容可改);
场景语法核心约束示例
数据只读,指针可移const 类型* 指针名不能改*指针名,可改指针名const int* p = &a; // *p=20错,p=&b对
指针只读,数据可改类型* const 指针名必须初始化,可改*指针名,不能改指针名int* const p = &a; // *p=20对,p=&b错
数据 + 指针都只读const 类型* const 指针名都不可改,必须初始化const int* const p = &a; // 全只读
示例

 

int a = 10, b = 20; // 场景1:数据只读,指针可移 const int* p1 = &a; // *p1 = 30; // 错误:内容只读 p1 = &b; // 正确:指针可移动 // 场景2:指针只读,数据可改 int* const p2 = &a; *p2 = 30; // 正确:内容可改 // p2 = &b; // 错误:指针地址只读 // 场景3:全只读 const int* const p3 = &a; // *p3 = 30; // 错误 // p3 = &b; // 错误 

场景 3:const 修饰引用(const 引用)

语法
const 类型& 引用名 = 变量/常量/临时值; 
核心作用
  1. 禁止通过引用修改原变量(引用只读);
  2. 可绑定常量 / 临时值(普通引用只能绑定可修改的左值);
  3. 绑定临时值时,临时值的生命周期会被延长至引用的生命周期结束。
示例

 

int a = 10; const int& ref1 = a; // ref1 = 20; // 错误:引用只读 const int& ref2 = 100; // 正确:const引用可绑定常量 double b = 3.14; const int& ref3 = b; // 正确:临时值(int(b))绑定到const引用,生命周期延长 
典型用途

函数参数传递(避免拷贝 + 防止修改):

 

// 自定义类型参数:const& 避免拷贝,且禁止修改参数 void printCircle(const Circle& c) { cout << c.calculateArea() << endl; // 只能调用c的const成员函数 } 

场景 4:const 修饰函数参数

语法
// 基础类型(传值,const仅约束函数内) void func(const int num) { /* num不可改 */ } // 自定义类型(推荐const&,避免拷贝+防修改) void func(const Circle& c) { /* c不可改 */ } // 指针参数(const修饰指向的内容) void func(const int* p) { /* *p不可改 */ } 
核心作用
  • 禁止函数内修改参数值,提升代码安全性;
  • 对自定义类型(如Circle),结合引用(const&)可避免拷贝,大幅提升效率;
  • 基础类型(int/double)传值时加const,仅约束函数内,对外部无影响(可加可不加)。

场景 5:const 修饰函数返回值

语法与作用

仅对「指针 / 引用返回值」有实际意义(基础类型返回值是拷贝,const 无作用):

// 场景1:返回const指针(禁止修改返回的内容) const int* func1(int* arr) { return arr; } // 场景2:返回const引用(禁止外部修改类成员) class Circle { private: double radius; public: const double& getRadius() const { return radius; } }; 
示例
int arr[] = {1,2,3}; const int* p = func1(arr); // *p = 10; // 错误:返回的指针指向内容只读 Circle c(5.0); // c.getRadius() = 10; // 错误:返回的引用只读 

场景 6:const 修饰类成员(核心!分变量 + 函数)

子场景 6.1:const 成员变量(类内常量)
语法(两种初始化方式)
  • C++11 及以上:类内直接初始化(简洁);
  • 所有 C++ 版本:构造函数初始化列表初始化(兼容推荐)。
// 写法1:C++11+ 类内直接初始化 class Circle { private: const double PI = 3.14159; // 类内初始化const成员 double radius; public: Circle(double r) : radius(r) {} }; // 写法2:初始化列表初始化(兼容所有版本) class Circle { private: const double PI; // 仅声明,不赋值 double radius; public: // 必须在初始化列表初始化const成员(不能在构造函数体赋值) Circle(double r) : PI(3.14159), radius(r) {} }; 
关键补充:静态 const 成员变量

若常量是所有对象共享的(如 PI),加static修饰,减少内存开销(所有对象共用一份):

class Circle { private: static const double PI = 3.14159; // 静态常量,类内初始化 double radius; }; // (可选)类外定义(若需跨文件访问) const double Circle::PI = 3.14159; 
子场景 6.2:const 成员函数(常量成员函数)
语法
返回值 函数名(参数列表) const; // const在参数列表后 
核心作用
  1. 约束函数不修改对象状态this指针变为const 类名*(只读指针),不能修改类的非mutable成员变量;
  2. 支持 const 对象调用:const 对象只能调用 const 成员函数(非 const 对象可调用 const / 非 const 函数);
  3. 语义标注:明确函数是 “只读操作”,提升可读性。
示例(Circle 类)

 

class Circle { private: double radius; mutable int calcCount = 0; // mutable:const函数中可修改 public: double calculateArea() const { // const成员函数 calcCount++; // 合法:mutable变量不受const约束 // radius = 10; // 错误:不能修改非mutable成员 return PI * radius * radius; } void setRadius(double r) { // 非const成员函数 radius = r; } }; // 使用场景 const Circle c1(5.0); c1.calculateArea(); // 正确:const对象调用const函数 // c1.setRadius(6.0); // 错误:const对象不能调用非const函数 Circle c2(5.0); c2.calculateArea(); // 正确:非const对象可调用const函数 c2.setRadius(6.0); // 正确:非const对象调用非const函数 
补充:mutable 关键字(const 函数的例外)

mutable修饰的成员变量,可突破 const 函数的约束(用于统计、缓存等不影响对象核心状态的场景):

 

class Circle { private: mutable int calcCount = 0; // 可在const函数中修改 public: double calculateArea() const { calcCount++; // 合法:统计函数调用次数 return PI * radius * radius; } }; 

场景 7:const 修饰对象(const 对象)

语法

 

const 类名 对象名(构造参数); 
核心作用

对象只读:只能调用 const 成员函数,不能修改任何成员变量(包括非 const 成员)。

示例
const Circle c(5.0); // c.setRadius(6.0); // 错误:const对象不能调用非const函数 cout << c.calculateArea() << endl; // 正确:调用const函数 

三、核心规则与易错点

  1. const 是编译期约束:仅在编译阶段检查,若通过const_cast强制修改 const 变量,会导致 “未定义行为”(可能崩溃 / 数据异常):
  2. const 的顺序
    • 普通变量:const int aint const a 等价;
    • 指针:const int* pint const* p 等价(左数),int* const p(右指)不同;
  3. const 引用绑定临时值:临时值(如10、表达式结果)的生命周期会被 const 引用延长至引用生命周期结束;
  4. const 成员函数调用规则
    • const 成员函数 → 只能调用其他 const 成员函数(避免间接修改对象);
    • 非 const 成员函数 → 可调用 const / 非 const 成员函数。
const int num = 10; int* p = const_cast<int*>(&num); *p = 20; // 未定义行为!编译器可能优化num为常量折叠,num仍为10 

四、常量正确性(Const Correctness)规范

遵循以下规范,可大幅减少编程错误:

  1. 所有只读数据(如 PI)用const修饰;
  2. 所有不修改对象状态的成员函数加const
  3. 函数参数若无需修改,加const(尤其是自定义类型的引用 / 指针参数);
  4. const 对象仅调用 const 成员函数,非 const 对象按需调用;
  5. 静态常量成员加static const,减少内存开销。

总结

Read more

从工具到自主伙伴:AI Agent + Skills 架构全解析(2026主流技术趋势)

一、引言 随着大模型技术的爆发式演进,AI 正在从「被动响应的工具」向「自主决策的伙伴」跃迁。对于开发者而言,理解 AI Agent 与 AI Skills 的技术脉络、协同逻辑,是把握下一代智能开发范式的关键。本文将基于行业最新技术图谱,系统拆解这一 2026 年即将成为主流的技术架构。 二、AI Agent 技术演进的三阶段 AI 智能体的发展并非一蹴而就,而是经历了从「单点响应」到「自主闭环」的三次技术跃迁: 1. 提示词驱动期(2022-2024) * 核心能力:文本交互、内容生成、简单问答 * 局限性:被动响应、无工具调用能力、依赖上下文记忆,无法处理复杂任务 * 典型场景:ChatGPT 基础问答、文案生成

By Ne0inhk
Flutter for OpenHarmony:tostore 鸿蒙原生 KV 数据库,支持 SQL 与 NoSQL 混合存储(全能型数据引擎) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:tostore 鸿蒙原生 KV 数据库,支持 SQL 与 NoSQL 混合存储(全能型数据引擎) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在移动应用开发中,数据持久化(Data Persistence)永远是架构设计中不可或缺的一环。无论是保存用户的登录状态、偏好设置,还是缓存新闻列表、聊天记录,选择一个合适的数据库往往决定了 App 的运行流畅度和开发效率。 在 Flutter 生态中,我们熟知的数据库方案琳琅满目: * Shared Preferences: 轻量级,但只适合存简单的 Key-Value,性能较差,且不支持复杂查询。 * Sqflite: 基于 SQLite 的封装,功能强大且稳定,但它是关系型数据库,Schema 变更(数库迁移)极其繁琐,且需要编写大量的 SQL 语句或依赖复杂的 ORM。 * Hive: 纯 Dart 编写的 NoSQL 数据库,速度极快(

By Ne0inhk
【MySQL数据库基础】(三)MySQL 库的核心操作全解析:创建、修改、备份一条龙搞定

【MySQL数据库基础】(三)MySQL 库的核心操作全解析:创建、修改、备份一条龙搞定

前言         在 MySQL 的学习和实战中,数据库(库)的操作是最基础也是最核心的环节,无论是项目开发、数据管理还是运维维护,都绕不开库的创建、配置、修改、备份等一系列操作。很多刚接触 MySQL 的小伙伴容易在字符集、校验规则、备份恢复这些细节上踩坑,今天这篇文章就结合实战案例,把 MySQL 库的全套操作讲透,从基础语法到高级技巧,从避坑指南到实战演示,让你一文掌握 MySQL 库操作的精髓! 一、创建数据库:基础语法与个性化配置         创建数据库是操作 MySQL 的第一步,看似简单的一句命令,背后却藏着字符集、校验规则的关键配置,选对配置能让后续的开发和数据管理少走很多弯路。 1. 核心创建语法         MySQL 中创建数据库的官方语法如下,其中大写部分为关键字,中括号[]内的为可选项,也是实际开发中需要重点关注的部分: CREATE DATABASE [IF NOT EXISTS]

By Ne0inhk
Flutter 组件 chopper_built_value 适配鸿蒙 HarmonyOS 实战:强类型网络层架构,构建不可变模型与高性能序列化闭环

Flutter 组件 chopper_built_value 适配鸿蒙 HarmonyOS 实战:强类型网络层架构,构建不可变模型与高性能序列化闭环

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 chopper_built_value 适配鸿蒙 HarmonyOS 实战:强类型网络层架构,构建不可变模型与高性能序列化闭环 前言 在鸿蒙(OpenHarmony)生态迈向大规模企业级应用、涉及高频网络数据交互、复杂业务模型及严苛运行时稳定性的背景下,如何确保网络请求返回的数据在进入 UI 层前具备绝对的类型安全,已成为衡量应用架构“护城河”深度的核心标准。在鸿蒙设备这类强调 AOT 极致性能与低容错率的环境下,如果应用依然依赖动态类型的 Map<String, dynamic> 进行数据传递,由于由于后端字段变更或类型溢出,极易由于由于运行时强转失败导致应用在关键业务路径上的红屏崩溃。 我们需要一种能够实现自动化代码生成、支持不可变(Immutable)模型且具备拦截器解耦能力的序列化粘合层。 chopper_built_value 为 Flutter 开发者引入了将 Chopper

By Ne0inhk