C++11新特性(24)-右值引用(续)

const引用


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


我们有以下一个Image类。


class Image
{
public
:
   
Image(int w, int h)
       
:width(w), height(h)
   
{
       
data = new char[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<char*>(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修饰符可以对外承诺不对参数进行修改的话,那么使用右值引用就是对外要求接管参数数据的权利。


觉得本文有帮助?请分享给更多人。
阅读更多更新文章,请扫描下面二维码,关注微信公众号【面向对象思考】

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值