标签:就是 程序 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");
标签:就是 程序 com tor 并发 调用 引用 内存 value
原文地址:https://www.cnblogs.com/lxy-xf/p/11539946.html