当前位置: 首页 > web >正文

C++中const的应用(1)之const 形参和实参以及成员函数的 const 和重载

1. 基本概念

  • 形参(formal parameter):定义函数时括号里写的变量名。
  • 实参(actual parameter):调用函数时传进去的具体值或变量。

加上 const 后:

类型意义
const 形参承诺函数内部不会修改传进来的参数
const 实参传入的值本身是常量或常量引用,防止被改动

2. 不同情况讲解

2.1 基本类型的 const 形参

如果是传值(不是引用或指针),const 修饰其实没太大意义(因为传值拷贝了一份,本来也不会影响原数据)。

void func1(const int x) {// x是拷贝来的副本,虽然加了const,但实际没必要
}

传值的话,const 是多余的,只能防止你在函数里改它。

2.2 指针或引用的 const 形参

更常见、更有意义的是指针或引用,加上 const

2.2.1 const 引用
void func2(const int& x) {// x是引用,但不能修改
}
  • 优点:避免复制(尤其是大对象)
  • 安全:保证不会改动传进来的数据

传对象也类似:

void printString(const std::string& str) {std::cout << str << std::endl;
}

常见于大对象传参,比如 std::stringstd::vector

2.2.2 const 指针

指针本身是常量

void func3(int* const p) {// p是常量指针(地址不能改,但*p可以改)
}

指向常量

void func4(const int* p) {// *p是常量(不能通过p修改*p)
}

组合例子

void func5(const int* const p) {// 地址不能改,指向的数据也不能改
}

3. 传实参时

  • 如果形参是 const T&,那么实参可以是:
    • 普通变量
    • 临时变量
    • const变量

例子:

void show(const std::string& str) {std::cout << str << std::endl;
}int main() {std::string s = "hello";show(s);                  // 普通变量show(std::string("world"));// 临时变量const std::string cs = "const";show(cs);                  // const变量
}

4. 小结口诀

  • 传值:小对象直接传,不必加 const
  • 传引用:大对象加 const &,又快又安全
  • 指针:明确谁是常量(指针本身,还是指向的内容)
  • 实参:只要类型兼容,都能传给 const 形参

5. 总结表

场景写法意义
小对象传值void foo(int x)不用 const,没影响
大对象传引用void foo(const std::vector<int>& v)节省拷贝,安全
修改指针指向内容void foo(int* p)可以改指向的内容
保护指针指向内容void foo(const int* p)不能改内容
固定指针地址void foo(int* const p)不能改指针本身

6. 成员函数的 const 和重载

6.1 为什么要加 const 成员函数?

如果一个成员函数不会修改对象的成员变量,就应该在函数后面加 const,告诉编译器和使用者:

这个函数承诺不会改对象

写法是:

class MyClass {
public:int getValue() const; // const成员函数
};

注意这里的 const 写在函数声明末尾,不是在参数里!

如果不加 const,那么用const对象调用时就出错了。


6.2 举例子:const和非const版本

来看个标准例子(比如一个自定义数组类):

#include <iostream>
#include <vector>class MyArray {
private:std::vector<int> data;
public:MyArray(std::initializer_list<int> list) : data(list) {}// 非const版本,允许修改元素int& operator[](size_t idx) {return data[idx];}// const版本,只读const int& operator[](size_t idx) const {return data[idx];}
};int main() {MyArray arr = {1, 2, 3, 4};arr[0] = 10; // 非const对象,调用非const版本,可以修改const MyArray arr2 = {5, 6, 7};std::cout << arr2[1] << std::endl; // const对象,只能调用const版本,只读
}

关键点总结

区别解释
int& operator[](size_t idx)返回非常量引用,可以赋值修改
const int& operator[](size_t idx) const返回常量引用,只能读,不能改

只有写了const版本,才能让 const对象 正常调用函数!


6.3 小扩展:普通成员函数 vs const成员函数

如果你有一个函数比如 getSize() 这样的:

size_t getSize() const {return data.size(); // 只读操作,安全
}

如果写成没有 const 的:

size_t getSize() {return data.size();
}

那么 const 对象就不能调用了!比如下面的写法会报错:

const MyArray arr = {1, 2, 3};
arr.getSize(); // ❌ 没有const版本会报错

所以原则是

  • 不改对象的成员变量 ➔ 写成 const 成员函数 ✅
  • 会改对象的成员变量 ➔ 正常函数,不加 const

7. 小总结

特性说明
const 成员函数声明时在函数末尾加 const
重载 const 和非const常见于 operator[]at()begin()/end()
const对象 只能调用 const成员函数所以经常要写两版

8. 延伸思考

如果类很大,想避免重复代码怎么办?可以const_cast 优雅复用(稍高级,后面进行讲解!)
比如写非const版本,然后const版本内部调用非const版。

http://www.xdnf.cn/news/2297.html

相关文章:

  • 从循环角度分析逐位分离法
  • 形象的讲解什么是Gateway网关
  • leetcode110 平衡二叉树
  • Ubuntu 之软件包管理系统
  • 前端技术个人求职简历模板
  • new/delete 重载与对象池实现
  • 高性能电脑系统优化工具Advanced SystemCare PRO v18.3.0.240 解锁永久专业版
  • 学习Spire.Office for Java版本的科学实践
  • 栈与队列 Part 2
  • 【NeurlPS 2024】MAR:无矢量量化的自回归图像生成
  • Jquery -函数调用使用创建立即执行函数
  • 代码随想录回文子序列
  • MQL5教程 06 EA开发实战
  • 【免费项目分享】(项目加说明文档)基于Go语言的城市电动汽车充电桩管理系统设计与实现
  • 深度学习原理与Pytorch实战
  • B. And It‘s Non-Zero
  • 八、Constants(常量)
  • Spring 学习笔记之 @Transactinal实现原理
  • Loki日志体系的搭建
  • Linux: 如何在VMware上安装Ubuntu操作系统
  • Redis 数据类型全览:特性、场景与操作实例
  • 泽润新能IPO隐忧:募资缩水2亿元,毛利率两连降,内控存瑕疵?
  • Eigen稀疏矩阵类 (SparseMatrix)
  • VS2019 与gitcode团队管理
  • QT6 源(52)篇二:存储 c 语言字符串的类 QByteArray 的使用举例,
  • Git基本操作
  • 第34课 常用快捷操作——按“空格键”旋转图元
  • MySQL技术白皮书
  • 定位与解决线上 OOM 问题:原因分析与快速排查指南
  • o4 - mini 助力,OpenAI 向免费用户推出轻量版 Deep Research