您的位置:首页 > 健康 > 养生 > 今日生猪价格一览表_财务公司管理系统_百度关键词关键词大全_艺人百度指数排行榜

今日生猪价格一览表_财务公司管理系统_百度关键词关键词大全_艺人百度指数排行榜

2025/5/20 20:25:38 来源:https://blog.csdn.net/qq_36812406/article/details/147543223  浏览:    关键词:今日生猪价格一览表_财务公司管理系统_百度关键词关键词大全_艺人百度指数排行榜
今日生猪价格一览表_财务公司管理系统_百度关键词关键词大全_艺人百度指数排行榜

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版。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com