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

版权声明:本文为博主原创文章,未经博主允许不得转载哦 (ÒωÓױ) https://blog.csdn.net/u012814856/article/details/83410552

一、引言

一直以来,我对于 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:)

猜你喜欢

转载自blog.csdn.net/u012814856/article/details/83410552