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

时间:2019-09-18
本文章向大家介绍C++11:移动语义与完美转发,主要包括C++11:移动语义与完美转发使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

转自

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");

  

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