C++ 函数参数传递方式总结:什么时候用值传递、引用、const 引用?

在 C++ 开发中,一个经常让人困惑的问题是:

函数参数到底该写 TT&,还是 const T&

很多人只记住一句话:
"大对象用 const 引用,小对象用值传递",

但背后的逻辑如果不理解,实际写代码时还是会犹豫。

这篇文章我们从 性能、语义、工程实践 三个角度,把参数传递方式一次讲清楚。

一、C++ 三种常见参数形式

1. 值传递(Pass by Value)

cpp 复制代码
void f(T x);

特点:

  • 拷贝一份对象
  • 函数内部改 x,不会影响外部
  • 简单直接

适用场景:

  • 小类型(int / double / bool / enum)
  • 函数需要"收下这份数据"
  • 要存入成员变量 / 容器

2. 引用传递(Pass by Reference)

cpp 复制代码
void f(T& x);

特点:

  • 不拷贝,直接操作原对象
  • 可以修改调用者的数据

适用场景:

  • 明确要 修改调用者对象
  • 工具函数 / 算法函数 / swap / normalize 等

3. 常量引用(Pass by Const Reference)

cpp 复制代码
void f(const T& x);

特点:

  • 不拷贝
  • 不允许修改
  • 性能好 + 语义清晰

适用场景:

  • 大对象只读访问
  • 打印 / 比较 / 计算 / 日志 / 序列化
  • std::string / vector / map / 自定义类

二、为什么不用 const T(值传 const)?

很多人会写:

cpp 复制代码
void f(const std::string s);

这其实 意义不大,因为:

  • 仍然会拷贝
  • const 只限制函数内部
  • 外部对象本来就不会被影响

所以:

const T 不能省拷贝,
const T& 才能省拷贝。

三、性能视角:什么时候会浪费资源?

大对象

cpp 复制代码
void f(std::string s);        // 会拷贝
void f(const std::string& s); // 不拷贝

拷贝 string / vector 可能涉及:

  • 内存分配
  • 数据复制
  • 构造析构

这是真正的资源浪费。

小对象

cpp 复制代码
void f(int x);          // 推荐
void f(const int& x);   // 没必要

原因:

  • int 只有 4 字节
  • 引用反而传 8 字节地址
  • CPU 寄存器传值更快

四、现代 C++ 的一个重要写法:值传 + move

当函数需要 保存参数 时,推荐这样写:

cpp 复制代码
class User {
    std::string name;
public:
    void setName(std::string n) {
        name = std::move(n);
    }
};

优点:

  • 左值调用:会拷贝
  • 右值调用:直接移动
  • 接口统一,调用舒服

这是现代 C++ 很常见的工程写法。

五、工程实践决策表

三个判断问题

1. 是否需要修改调用者?
  • 是 → T&

  • 否 → 继续

2. 是否是小类型?
  • 是 → T

  • 否 → 继续

3. 是否要保存参数?
  • 是 → T + move

  • 否 → const T&

六、快速记忆口诀

可以直接背这一句:

改它:T&
小的:T
大的只读:const T&
要收下:T + move

七、典型示例对照

小类型

cpp 复制代码
void setAge(int age);

大对象只读

cpp 复制代码
void print(const std::string& s);

修改对象

cpp 复制代码
void normalize(std::vector<int>& v);

存储对象

cpp 复制代码
void setName(std::string name);

八、总结

C++ 参数传递的本质不是语法问题,而是:

  • 性能
  • 语义表达
  • 工程可维护性

真正的原则不是死记硬背,而是理解:

我是"借来看一眼",

还是"要动它",

还是"要收下它"。

理解这一点,你写出的函数签名就会自然、专业、工程化。

相关推荐
Felven2 小时前
C. Yet Another Card Deck
c语言·开发语言
「QT(C++)开发工程师」2 小时前
【Qt Creator 15.0.1 安装指南】
开发语言·qt
网小鱼的学习笔记2 小时前
leetcode283移动零元素
java·开发语言·算法
一点多余.2 小时前
java中的单例模式
java·开发语言·单例模式
xyq20242 小时前
NumPy 创建数组
开发语言
紫陌涵光2 小时前
538. 把二叉搜索树转换为累加树
c++·算法·leetcode
lly2024062 小时前
Ruby 类和对象
开发语言
Dovis(誓平步青云)2 小时前
《C/C+++ Boost 轻量级搜索引擎实战:架构流程、技术栈与工程落地指南——构造正/倒排索引(中篇)》
开发语言·c++·搜索引擎
Autumn72992 小时前
【系统重装】PYTHON 入门——速通版
开发语言·python·conda·cuda
keyborad pianist2 小时前
Java应用基础 Day3
java·开发语言