C++ 参数传递方式全解析(多种方式)

 更新时间:2025年09月20日 14:27:36   作者:没有天赋那就反复  
C++支持值、指针、引用、const引用、移动语义等参数传递方式,值传递适用于小型数据,引用/const引用用于大型对象或只读访问,移动语义优化资源管理,数组需传递大小,本文给大家介绍C++ 参数传递方式,感兴趣的朋友一起看看吧

C++ 提供了多种参数传递方式,每种方式都有其特定的用途和性能特征。下面我将详细解释各种传递方式,并通过示例代码进行演示。

1. 值传递 (Pass by Value)

值传递会创建参数的完整副本,函数内对参数的修改不会影响原始变量。

#include <iostream>
using namespace std;
void modifyValue(int x) {
    x = x + 10;  // 修改的是副本,不影响原始值
    cout << "函数内值: " << x << endl;
}
int main() {
    int a = 5;
    cout << "调用前: " << a << endl;
    modifyValue(a);
    cout << "调用后: " << a << endl;  // 仍然是5
    return 0;
}

特点

  • 创建参数的完整副本
  • 函数内修改不影响原始值
  • 适用于小型数据类型(int, float, char等)
  • 对于大型对象,复制开销较大

2. 指针传递 (Pass by Pointer)

指针传递传递的是变量的内存地址,函数内可以通过指针修改原始值。

#include <iostream>
using namespace std;
void modifyPointer(int* x) {
    *x = *x + 10;  // 通过指针修改原始值
    cout << "函数内指针值: " << *x << endl;
}
int main() {
    int a = 5;
    cout << "调用前: " << a << endl;
    modifyPointer(&a);  // 传递地址
    cout << "调用后: " << a << endl;  // 变为15
    return 0;
}

特点

  • 传递内存地址
  • 函数内修改会影响原始值
  • 可以传递nullptr
  • 需要解引用操作(*)
  • 语法相对复杂,可能产生空指针问题

3. 引用传递 (Pass by Reference)

引用传递传递的是变量的别名,函数内对引用的修改会影响原始值。

#include <iostream>
using namespace std;
void modifyReference(int& x) {
    x = x + 10;  // 修改引用即修改原始值
    cout << "函数内引用值: " << x << endl;
}
int main() {
    int a = 5;
    cout << "调用前: " << a << endl;
    modifyReference(a);  // 直接传递变量
    cout << "调用后: " << a << endl;  // 变为15
    return 0;
}

特点

  • 传递变量的别名
  • 函数内修改会影响原始值
  • 语法简洁,无需解引用
  • 比指针更安全(不能为null)
  • 是C++中推荐的修改参数的方式

4. const引用传递 (Pass by const Reference)

const引用传递可以避免大型对象的复制开销,同时保护原始数据不被修改。

#include <iostream>
#include <string>
using namespace std;
void printString(const string& s) {
    cout << "字符串内容: " << s << endl;
    // s += " modified"; // 错误:不能修改const引用
}
int main() {
    string str = "这是一个很长的字符串,使用值传递会产生复制开销";
    printString(str);  // 避免复制,同时保护原始数据
    cout << "原始字符串未改变: " << str << endl;
    return 0;
}

特点

  • 避免大型对象的复制开销
  • 保护原始数据不被修改
  • 适用于大型对象(字符串、容器、自定义对象等)
  • 是C++中传递大型对象的推荐方式

5. 移动语义传递 (C++11)

移动语义传递通过转移资源所有权来避免不必要的复制,特别适用于管理资源的对象。

#include <iostream>
#include <vector>
#include <utility>  // for std::move
using namespace std;
void processVector(vector<int>&& v) {
    cout << "移动传递 - 向量大小: " << v.size() << endl;
    // 可以修改v,但原始向量将变为空
    v.push_back(99);
    cout << "修改后大小: " << v.size() << endl;
}
int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    cout << "移动前向量大小: " << vec.size() << endl;
    processVector(move(vec));  // 显式转移所有权
    cout << "移动后向量大小: " << vec.size() << endl;  // 变为0
    return 0;
}

特点

  • 转移资源所有权,避免复制
  • 使用std::move()显式转移
  • 适用于可移动对象(vector, string, 自定义移动语义的对象)
  • 原始对象将处于有效但未定义的状态

6. 数组传递

C++中数组传递实际上是指针传递,需要额外传递数组大小信息。

#include <iostream>
using namespace std;
void printArray(int arr[], int size) {
    cout << "数组元素: ";
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
        arr[i] += 1;  // 修改会影响原始数组
    }
    cout << endl;
}
int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int size = sizeof(arr) / sizeof(arr[0]);
    cout << "调用前第一个元素: " << arr[0] << endl;
    printArray(arr, size);
    cout << "调用后第一个元素: " << arr[0] << endl;  // 变为2
    return 0;
}

特点

  • 实际上传递的是指向数组首元素的指针
  • 需要额外传递数组大小信息
  • 函数内修改会影响原始数组
  • 可以使用std::array或std::vector替代原始数组

7. 默认参数

函数可以指定默认参数,调用时可以省略这些参数。

#include <iostream>
using namespace std;
// 默认参数必须在函数声明中指定
void printMessage(string message = "Hello, World!", int times = 1) {
    for (int i = 0; i < times; i++) {
        cout << message << endl;
    }
}
int main() {
    printMessage();  // 使用所有默认参数
    printMessage("Hi!");  // 使用默认times
    printMessage("C++ is great!", 3);  // 不使用默认参数
    return 0;
}

特点

  • 允许函数调用时省略某些参数
  • 默认值必须在函数声明中指定
  • 默认参数必须从右向左连续设置

8. 可变参数模板 (C++11)

可变参数模板允许函数接受任意数量和类型的参数。

#include <iostream>
using namespace std;
// 基础案例 - 递归终止函数
void print() {
    cout << endl;
}
// 可变参数模板
template<typename T, typename... Args>
void print(T first, Args... args) {
    cout << first << " ";
    print(args...);  // 递归调用
}
int main() {
    print(1, 2.5, "hello", 'a');  // 输出: 1 2.5 hello a 
    return 0;
}

特点

  • 接受任意数量和类型的参数
  • 提供类型安全的可变参数处理
  • 使用递归模板展开参数包
  • C++11及以上版本支持

9. 函数对象传递

C++中函数也可以作为参数传递,通常通过函数指针、std::function或lambda表达式实现。

#include <iostream>
#include <functional>
using namespace std;
// 使用函数指针
void process(int x, int y, int (*func)(int, int)) {
    cout << "结果: " << func(x, y) << endl;
}
// 使用std::function(更灵活)
void processFunction(int x, int y, function<int(int, int)> func) {
    cout << "结果: " << func(x, y) << endl;
}
int add(int a, int b) {
    return a + b;
}
int multiply(int a, int b) {
    return a * b;
}
int main() {
    // 函数指针传递
    process(5, 3, add);
    process(5, 3, multiply);
    // std::function传递
    processFunction(5, 3, add);
    // Lambda表达式传递
    processFunction(5, 3, [](int a, int b) { return a - b; });
    return 0;
}

总结与选择指南

传递方式适用场景优点缺点
值传递小型数据类型简单安全,不影响原始值复制开销大(大型对象)
指针传递需要修改原始值,可选参数可以修改原始值,可以传递null语法复杂,可能空指针异常
引用传递需要修改原始值语法简洁,比指针安全不能传递null
const引用大型对象,只读访问避免复制,保护原始数据不能修改参数
移动语义资源管理对象避免复制,转移所有权原始对象状态未定义
数组传递C风格数组直接操作数组元素需要额外传递大小信息
默认参数简化函数调用调用灵活必须从右向左设置
可变参数参数数量不定高度灵活,类型安全实现复杂

一般建议

  1. 对于基本数据类型,使用值传递
  2. 需要修改参数时,使用引用传递
  3. 对于大型对象,使用const引用传递
  4. 需要转移资源所有权时,使用移动语义
  5. 避免使用原始指针传递,优先使用引用或智能指针

这些传递方式可以根据实际需求组合使用,以满足不同的编程场景。

到此这篇关于C++ 参数传递方式全解析(多种方式)的文章就介绍到这了,更多相关C++ 参数传递内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++笔记-设置cout输出数据的宽度和填充方式

    C++笔记-设置cout输出数据的宽度和填充方式

    这篇文章主要介绍了C++笔记-设置cout输出数据的宽度和填充方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C/C++获取目录下的文件列表信息

    C/C++获取目录下的文件列表信息

    在C/C++编程时,需要获取目录下面的文件列表信息,下面把代码分享一下
    2014-02-02
  • 用C语言实现计算器功能

    用C语言实现计算器功能

    这篇文章主要为大家详细介绍了用C语言实现计算器功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • C++用easyx图形库实现障碍跑酷小游戏

    C++用easyx图形库实现障碍跑酷小游戏

    这篇文章主要为大家详细介绍了C++用easyx图形库实现障碍跑酷小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • C++使用MFC获取PC硬件配置信息

    C++使用MFC获取PC硬件配置信息

    这篇文章主要为大家详细介绍了C++使用MFC获取PC硬件配置信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • C++ Boost log日志库超详细讲解

    C++ Boost log日志库超详细讲解

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • VC++创建msi文件的方法

    VC++创建msi文件的方法

    这篇文章主要介绍了VC++创建msi文件的方法,对于应用程序的开发有一定的借鉴价值,需要的朋友可以参考下
    2014-07-07
  • c++函数名指针和函数指针

    c++函数名指针和函数指针

    这篇文章主要介绍了c++函数名指针和函数指针,函数指针和数据类似,C++当中函数也有地址,函数的地址是存储函数机器语言代码的内存地址。我们可以将另外一个函数的地址作为参数传入函数,从而实现函数的灵活调用,下面详细内容需要的小伙伴可以参考一下
    2022-02-02
  • C++ STL-string类底层实现过程

    C++ STL-string类底层实现过程

    本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强调了内存管理与边界检查
    2025-08-08
  • c/c++中变量的声明和定义深入解析

    c/c++中变量的声明和定义深入解析

    “声明”为编译服务,用于类型检查 ;“定义”在运行时会分配空间,不能重复定义,同时具备声明的功能
    2013-09-09

最新评论