C++细节(二)

3.1 左值引用

左值引用,其声明是通过在某个类型后放置一个 & 符号来进行的。

此时,一个左值引用成为了它所引用的对象的同义词。如图

当然,左值引用有以下的几个用途:

1. 给结构复杂的名称起别名

  auto & whichList = theList[myhash( x, theList.size() )];  //起别名

  if (find(begin(whichList),end(whichList),x)!=end(whichList))

    return false;

  whichList.push_back(x);

2. 范围for 循环

   for (auto & x :arr) ++x;     //arr 为vector 对象

实际上也是让x是vector中每个值的另一个名字,使for循环变得更简洁一些。

3. 避免复制

假设有一个findMax函数是返回一个大集合中的最大值,用左值引用可以避免对象的复制。如,

    auto &x =findMax( arr ); //而不是用auto x=findMax( arr )

3.2 参数传递

C++11中有4种传递参数的方法:

1.传值调用

在许多编程语言中,运用传值调用传递所有参数。而它却不是C++11的唯一传递机制。传值调用使的原实际参数保持不变。

2.传引用调用

比如,swap (x,y)需要交换x和y 的值,即改变x和y 的值就不能用传值调用的方法。交换函数的定义如下:

  viod swap(&x ,&y) {....}

3.传常量引用调用

对于 string randomItem( vector<string> arr) 函数是返回arr 中的一个随机项,未对其做任何改变。

而其中,传值调用的使用使vector 对象进行了复制,增加了程序运行的开销,是应避免使用的做法。

因此,传常量引用调用可以通过声明arr 为对vec 的常量引用以避免复制而达到相同的语义效果,如下:

string randomItem( const vector<string> & arr);

4.传右值引用调用

其核心概念在于,由于右值存储的是要被销毁的临时量,像 x=rval可以通过移动而不是复制实现。

4种传递参数选择的注意事项:

1. 对于小的不应被函数改变的对象,选择传值调用合适。

2. 对于大的不应被函数改变的且复制代价昂贵的对象,采取传常量引用调用合适。

3. 对于所有可以被函数改变的对象,则选择传引用调用。

参考资料:https://blog.csdn.net/u012814856/article/details/83410552

3.3 返回值传递

同样在C++中函数返回也有几种机制。不同类型的返回应选择相应的返回机制,以提高程序的效率,如

  double avg( double x,double y);           //返回均值

  LargeType random(const vector<LargeType> &arr);   //潜在低效

  vector<int> partialSum(const vector<int> &arr);     //较高效

代码的第一行是传值返回,是一种简单直接的机制。对于第三行则需要运用传常量引用返回以避免直接复制,具体代码如下所示,

LargeType random1( const vector<LargeType> &arr )

{

return arr[random(0,arr.size()-1)];

}

const LargeType random2( const vector<LargeType> &arr )

{

return arr[random(0,arr.size()-1)];

}

Vector< LargeType> vec;

....

LargeType item1 = random1(vec); //复制

LargeType item2 = random2(vec); //复制

const LargeType &item3 =random2(vec); //不复制

注意,传常量引用返回的调用者必须也使用常量引用以存取这个返回值,否则仍将进行复制。

第三种是传引用返回 ,既不产生拷贝,并且还能对其值进行修改(这种情况虽然少见,但是也有存在)。

参考资料:https://blog.csdn.net/u012814856/article/details/84099328

猜你喜欢

转载自www.cnblogs.com/lincz/p/10686748.html