打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C 11新特性(24)-右值引用(续)

const引用

在C++语言中,引用是作为一种高效,安全的传递数据的方式而存在的。除了一般的引用类型,还可以声明const引用。

先看下面的Image类。

class Image{ public:  Image(intw,inth)   :width(w),height(h)  {   data=newchar[getSize()];  }  int getSize(){   return width*height;  }  virtual ~Image(){   if(data!=nullptr){    delete data;    data=nullptr;    width=0;    height=0;   }  }private:  int width=0;  int height=0;  char* data=nullptr;}

上面只是这个类的雏形,只有构造函数,析构函数和取得数据大小的功能。

接下来添加比较两个Image是否相同的函数。最简单的形式大致如下。

bool isSame(Image& img){  if(width==img.width   &&height==img.height){   return (memcmp(data,img.data,getSize())==0);  }  else{   return false;  }}

这里使用引用类型的参数,避免了没有必要的拷贝动作。当然我们还可以做得更好:由于比较函数没有必要也不应该对比较对象的内容进行修改,所以还可用下面的形式进行承诺:

bool isSame(const Image& img){  if(width==img.width  &&height==img.height){  char* in=static_cast(img.data);   return (memcmp(data,in,getSize())==0);  }  else{   return false;  }}

通过在参数前面增加const修饰符,向isSame方法的调用者保证,不会修改img的内容。

右值引用

继续添加将一个Image的一部分merge到另一个Image上的方法。函数的内容大致如下(这里忽略处理的细节):

void merge(Image& img){  //接管img中的数据。  img.height=0;  img.width=0;  img.data=nullptr;}

类似的操作在处理在输入对象时一般有两种处理方式。有时希望只是参照而不破坏输入数据,这时可以使用前面讲到的为参数增加const修饰符的方式来承诺;有时为了提高效率或者其他的原因希望可以接管输入的数据,就像上面代码的状态。这时的行为更像是数据移动。

对于第二种方式,如果仅仅定义一般的引用类型,利用者根本没有办法通过方法声明来确定这个操作是否会接管参数中的数据。这种不确定性会造成很大的麻烦。

解决这个问题的方法就是今天文章的题目--右值引用。代码如下:

void merge(Image&& img){  //接管img中的数据。  img.height=0;  img.width=0;  img.data=nullptr;}

我们将参数声明为右值引用,要求像一个临时变量一样任性地使用数据。使用这个函数的方法如下:

Image img1(100,100);Image img2(100,200);img1.merge(std::move(img2));

注意代码中的std::move,这是标准库中提供的方法,它可以将左值显式转换为右值引用类型,从而告诉编译器,可以像右值(临时变量)一样处理它。同时也意味着接下来除了对img2赋值或销毁以外,不再使用它。

C++11通过使用右值引用提供了一种接管数据的标准方法。

作者观点

如果说使用const修饰符可以对外承诺不对参数进行修改的话,那么右值引用就是对外要求接管参数数据的权利。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
1小时快速掌握中医内科学(病证、定义、证型、治法、方药)
mui H5+ 调取 相册 拍照 功能 上传图片 + 裁剪功能
GDI+学习及代码总结之
Qt(C++) 截屏的方法
【精彩女人】中国古典淑女
虔诚
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服