【C++】015、函数参数:值传递,指针传递,引用传递的区别

一、本质区别

1、值传递是赋值粘贴,函数内获取的副本,不影响外部

2、指针传递的是“邮寄地址”,可通过地址间接修改外部对象

3、引用传递的是别名绑定,可直接操作原对象

二、比对

对比维度

值传递

指针传递

引用传递

传递内容

实参的副本(全新拷贝)

实参地址(拷贝地址值)

实参的别名(底层也是地址)

能否修改外部实参

不能(改的是副本)

能(通过解引用*ptr)

能(直接操作原对象)

内存开销

打(拷贝整个对象)

小(拷贝8字节地址)

空值(null)风险

有(空指针需判断空)

无(引用必须事先绑定对象)

  • 代码:

#include <iostream> #include <string> // 1. 值传递:改的是副本 void byValue(std::string s) { s += "_copy"; // 只影响局部副本 } // 2. 指针传递:通过地址修改原对象 void byPointer(std::string* s) { if (s) { // 必须判空! *s += "_ptr"; } } // 3. 引用传递:直接修改原对象 void byReference(std::string& s) { s += "_ref"; } int main() { std::string str = "Hello"; byValue(str); std::cout << str << std::endl; // 输出 "Hello"(未变) byPointer(&str); std::cout << str << std::endl; // 输出 "Hello_ptr" byReference(str); std::cout << str << std::endl; // 输出 "Hello_ptr_ref" }

三、引用使用场景

1、需要修改实参

void swap(int& a, int& b) { int tmp = a; a = b; b = tmp; }

2、传递大对象,只读不写使用const引用

void printVector(const std::vector<int>& v) { // 避免拷贝百万个元素 for (int x : v) std::cout << x; }

3、保留派生类信息,实现多态

class Animal { virtual void speak(){} }; class Cat : public Animal { void speak() override {} }; void play(Animal& a) { a.speak(); } // 传 Cat 也能正确调用 Cat::speak()

4、运算符重载

int& operator[](size_t idx) { return data[idx]; }

四、使用指针的场景

1、参数可选,可能为空

2、需要动态改变指针指向的对象

  • 指针可指向另外的对象地址,而引用不允许

3、与C语言交互,C语言没有引用,使用指针传递(void*)