细谈 C++ 传参的四种方式:按值传参、按左值引用传参、按常量引用传参以及按右值引用传参

一、引言

一直以来,我对于 C++ 的传参方式只有皮毛上的了解而没有深入其里的探讨。正好,最近在学习《Data Stuctures And Algorithms Analysis In Cpp 4th Edition》这本书的时候,看到作者介绍 C++ 及其 C++11 的传值调用的四种方式的时候,顿觉恍然大悟,有种想要整理一下分享给广大网友的冲动,因此写下了这篇博客。

在这篇博客里,我会像作者那样,首先介绍下传统 C++ 和 C++11 新增的共四种传参方式,然后总结四种传参方式的特点,最后探讨下在实际开发过程中我们该如何选择的问题。

ps: 本篇博客大量参考了《Data Structures And Algorithms Analysis In Cpp 4th Edition》中的解释和代码。也大力推荐各位网友看看这本书,讲解的非常细致到位。

二、传统 C++ 的三种传参方式

我们知道 C 和 Java 都只有一种传参方式,那就是按值传参。

然而,对于 C++ 来说,按值传递一个非常复杂的对象是非常耗费资源的,也是非常低效的。

因此,传统 C++ 理论上是存在三种传参方式的,除了最基本的按值传参,还衍生出来了按引用传参,以及按常量引用传参。

1. 按值传参
按值传参的概念非常好理解,就是函数接收到了传递过来的参数后,将其拷贝一份,其函数内部执行的代码操作的都是传递参数的拷贝。

也就是说,按值传参最大的特点就是不会影响到传递过来的参数的值,但因为拷贝了一份副本,会更浪费资源一些。

double average( double a, double b);
double z = average( x, y );

当调用了 average 函数之后,按值传参就会将 x 复制给 a,y 复制给 b。因此不会影响到原来的 x 和 y 的值。

2. 按(左值)引用传参
按值传参不会影响到原来的参数的值,那么问题来了,如果我们就是想要对参数进行一些修改,怎么办呢?这时候按(左值)引用传参就应运而生了。

void swap ( double & a, double & b);
swap( x, y);

当我们调用 swap 的时候,a 相当于 x 的别名,b 相当于 y 的别名,对于 a 和 b 的修改,同时也就应用到了 x 和 y 上面。

也就是说,当我们想要对传入参数进行一些修改的时候,按(左值)引用传参绝对是最适合的。

3. 按常量引用传参
我们之前说了,如果想要对传入参数进行一些修改,我们要使用按(左值)引用传参,那么我们不想要对传入参数进行修改,是不是就只能使用按值传参了呢?我们能不能既拥有引用的节省拷贝开支的优点,又拥有按值传参的不影响原值的优点呢?

于是乎,按常量引用传参也就应运而生了。如果我们只是想要看一看参数的值,而并不需要去修改它,我们就可以使用按常量引用传值,从而减少拷贝方面的开销。

string randomItem( const vector<string> & arr );
vector<string> v { "hello", "world" };
cout << randomItem( v ) << endl;

此时,我们使用按常量引用传参就会比按值传参节省一次拷贝开销。

三、C++11 新增的按右值引用传参

C++11 全面引入移动语义:

x = y
can be a copy if y is an lvalue,
but a move if y is an rvalue.

对于右值来说,其存储的是临时的将要被摧毁的资源,移动一个对象的状态总会比赋值这个对象的状态要来的简单(开销小)。

string randomItem( vector<string> && arr );
vector<string> v { "hello", "world" };
cout << randomItem( { "hello", "world" }) << endl;

四、实际开发中该如何选择

我们上面说了四种传参方式,那么实际开发中,我们该如何选择呢?

这里我特地画了一个图:

在这里插入图片描述

希望能给大家一些帮助 ^_^

五、总结

熟悉 C++ 的四种传参方式,其实是一件很重要的事情,其直观反映到了我们编写的代码中去。尽管按值传参大部分情况下都能够使用,但是合适的情况下使用合适的传参方式体现了我们对于 C++ 的理解深度。

另外,或许有人会问,诶,不是还有一种按地址传参的方式吗?

我们来仔细想想,按地址传参,其实不就是按值传参吗?传递的就是参数的地址而已。

不得不说 《Data Stuctures And Algorithms Analysis In Cpp 4th Edition》真是一本好书,很多时候能让我有不一样的领悟和感慨。也由衷的推荐给大家!

To be Stronger:)

  • 20
    点赞
  • 72
    收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 8

打赏作者

曾经去过跨越一个小时的地方

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值