码迷,mamicode.com
首页 > 移动开发 > 详细

C++11:移动语义与完美转发

时间:2019-09-18 11:26:30      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:就是   程序   com   tor   并发   调用   引用   内存   value   

转自

https://www.cnblogs.com/jianhui-Ethan/p/4665573.html

C++11 引入的新特性中,除了并发内存模型和相关设施,这些高帅富之外,最引人入胜且接地气的特性就要属『右值引用』了(rvalue reference)。加入右值引用的动机在于效率:减少不必要的资源拷贝。考虑下面的程序:

std::vector<string> v;
v.push_back("string");

首先看push_back:

push_back(const T& x)

实际上传进来的是引用

而在push_back中构造时,使用的是construct:

void construct(T1* p,const T2& value)
{
  new(p) T1(value);  
}

  T1*为迭代器所指的位置,而构造的值value也是引用。T1为迭代器类型,而p为该迭代器所处的地址,也就是说construct实际上是在迭代器所属位置上,用value来构造一个T1类型的迭代器。

这里值得要注意的是,容器对其中存储元素的管理都是在堆上的(用自由存储区更精确),也就是说容器本身可能是在栈上,但它管理的元素一定是在堆上。

在回到上面的过程:

首先"string"这是一个char*指向的区域,而push_back调用的实际上里面是一个string&变量,因此首先进行隐式转换,调用string的string(const char*)这个含参的构造函数。

而这个生成的变量其实上是一个临时变量。

push_back可以看到他是传参的,因此这个临时变量直接被传进去而没有被拷贝构造。

到目前为止,使用了隐式转换,而这次隐式转换调用了含参(char*)的string的构造函数。

进入之后进入construct,而construct也是传引用,因此这里也没有调用构造。

但是在construct内部,在new时,使用了T1的含参构造,相当于在堆上利用这个临时变量构造了一个T1类型的变量

在这里调用了一次构造。

而由于vector的迭代器是原始指针,因此这里T1与T2是同一种类型(当然对其他容器就不一定是这样了)

因而调用的实际上是拷贝构造

在堆上构造完毕后,construct退栈,push_back退栈,然后这个临时变量因为离开作用域而被析构

实际上这个过程经历了一次含参构造,一次拷贝构造,一次析构

std::vector<string> v;
v.push_back("string");

  

C++11:移动语义与完美转发

标签:就是   程序   com   tor   并发   调用   引用   内存   value   

原文地址:https://www.cnblogs.com/lxy-xf/p/11539946.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!