C++11新特性应用--让你的程序更高效(右值引用避免深拷贝)

这里的内容注意参考书籍《深入应用C++11代码优化与工程级应用》

今天,重温一下右值。

使用右值,使得我们的C++程序更加高效。

我们可以简单把右值理解为一个临时变量。之前,我们谁也不会在意这个临时变量,但要付出了效率的代价。

而右值引用就是对右值进行的引用类型,与我们通常所说的引用一样,一定要记得初始化。

左右值区分:

void func(X& x); // 左值引用 重载
void func(X&& x); // 右值引用 重载

X x;
X foobar();

func(x); // 参数为左值,调用func(X& x);
func(foobar()); // 参数为右值,调用func(X&& x);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

再看看这个:

// lvalues:
  //
  int i = 42;
  i = 43; // ok, i is an lvalue
  int* p = &i; // ok, i is an lvalue
  int& foo();
  foo() = 42; // ok, foo() is an lvalue
  int* p1 = &foo(); // ok, foo() is an lvalue

  // rvalues:
  //
  int foobar();
  int j = 0;
  j = foobar(); // ok, foobar() is an rvalue
  int* p2 = &foobar(); // error, cannot take the address of an rvalue
  j = 42; // ok, 42 is an rvalue
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

之前在初始化列表的博客中提到过,使用初始化列表进行初始化,比在构造函数中初始化效率更高,道理是一样的。

这结论一定是正确的,当你用VS编译器试图写代码进行验证的时候,你也许就会骂娘了,这他妈输出结果不是一样的吗。

我只能呵呵了,因为编译器对程序进行了优化,你是看不到的。如果非要搞明白,就试图一步一步看看反汇编吧,包你满意。

下面就说说使用右值如何避免深拷贝。

此时,你可能又要犯嘀咕了? 
深拷贝不是好事儿吗,使我们自己写的赋值构造函数实现深拷贝吗,是为了避免两个指针指向同一个东西,也避免删除同一个东西两次。

但,凡是都是在不停的发展的。因为C++11引入了右值概念,所以这就使得之前我们所写的赋值构造函数并不是那么完美了。主要还是效率的问题了。

下面就是用到了移动构造函数~之前也有提到过啊:

MyString(MyString&& str) {  
         std::cout <<"Move Constructor is called! source: "<< str._data << std::endl;  
         _len = str._len;  
         _data = str._data;         // 避免了不必要的拷贝  
         str._len = 0;  
         str._data = NULL;  
}  

MyString&operator=(MyString&& str) {  
         std::cout <<"Move Assignment is called! source: "<< str._data << std::endl;  
         if (this != &str) {  
                      _len = str._len;  
                      _data = str._data;    // 避免了不必要的拷贝  
                      str._len = 0;  
                      str._data = NULL;  
         }  
         return *this;  
} 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

有了右值引用和移动语义,在设计和实现类时,对于需要动态申请大量资源的类,应该设计右值引用的拷贝构造函数和赋值函数,以提高应用程序的效率。需要注意的是,我们一般在提供右值引用的构造函数的同时,也会提供常量左值引用的拷贝构造函数,以保证移动不成还可以使用拷贝构

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值