文章目录
资料
[c++11]我理解的右值引用、移动语义和完美转发
c++右值引用以及使用
C++ 引用占用内存?
C++11右值引用(一看即懂)
从4行代码看右值引用
函数的返回值保存在内存的什么区域
C++11特性之右值引用及完美转发
说明
需要明确:右值引用是c++11的。
可以先简单记忆为,右值是不可取地址的,左值是可取地址的。
需要理解:引用本质上是一种 带有限制的指针。
问题来源
有时,一个函数的返回值 是直接连接到 下个函数的。
在内存使用上,我们希望把 返回值的内存 直接交给 下个函数直接使用,
去除在不同函数间,拷贝数据时的时间和内存消耗。
测试
约定环境
#include <iostream>
//唯一标识一个类
int ID=0;
//用来测试的类
class A{
public:
int id;
A():id(ID){
ID++;
std::cout<<"construct "<<id<<std::endl;
}
A(const A& a):id(ID){
ID++;
std::cout<<"copy construct "<<id<<std::endl;
}
~A(){
std::cout<<"destruct "<<id<<std::endl;
}
};
//调用对象
void fun(A& a) {std::cout<<"> main::fun() "<<a.id<<std::endl;}
//临时函数,负责返回一个对象
A tempFun() {return A();}
测试实例
基本调用,使用 返回值优化
//命令: g++ cpp11test.cpp
int main(){
std::cout<<"---------"<<std::endl;
tempFun();
std::cout<<"---------"<<std::endl;
}
/*输出
---------
construct 0
destruct 0
---------
*/
//如果有变量接着
int main(){
std::cout<<"---------"<<std::endl;
A a=tempFun();
std::cout<<"---------"<<std::endl;
}
/*输出
---------
construct 0
---------
destruct 0
*/
基本调用,不使用 返回值优化
//命令: g++ cpp11test.cpp -fno-elide-constructors
int main(){
std::cout<<"---------"<<std::endl;
tempFun();
std::cout<<"---------"<<std::endl;
}
/*输出
---------
construct 0
copy construct 1
destruct 0
destruct 1
---------
*/
使用左值引用,不使用 返回值优化
//命令: g++ cpp11test.cpp -fno-elide-constructors
int main(){
std::cout<<"---------"<<std::endl;
A a=tempFun();
std::cout<<"---------"<<std::endl;
fun(a);
}
/*输出
---------
construct 0
copy construct 1
destruct 0
copy construct 2
destruct 1
---------
> main::fun() 2
destruct 2
*/
使用右值引用,不使用 返回值优化
//命令: g++ cpp11test.cpp -fno-elide-constructors
int main(){
std::cout<<"---------"<<std::endl;
A&& a=tempFun();
std::cout<<"---------"<<std::endl;
fun(a);
}
/*输出
---------
construct 0
copy construct 1
destruct 0
---------
> main::fun() 1
destruct 1
*/
结论的
关于函数调用
根据资料得知,调用者 会给与 被调用者 一个临时内存空间来存储返回值。
在被调用者一侧,会将生成好的对象复制一份到 调用者给予的临时空间
在调用者一侧,左值引用会 从临时空间中复制一份,右值引用会 直接使用临时空间
根据资料和猜测,返回值优化会改变正常的 栈堆形式的函数调用
我没有细致考虑真实情况(待补充~~咕咕咕咕咕咕)
关于左右值
抄写的资料:
1.已命名的右值引用,编译器会认为是个左值
个人的理解:
1.利用右值引用扩张临时变量的生存时间,但应当注意,变量使用的是临时的内存空间,个人认为应当尽快使用并离开这段空间。
关于引用
本质上和指针没有区别,规则和限制 是编译器做的。(个人没听说过汇编能做限制)
关于返回值优化
根据资料,并不是所有情况编译器都能帮助进行返回值优化
比如在返回值是一个表达式的时候