分享

右值引用

 quasiceo 2012-11-23

///////////////////////////////////////////////

我的注解

int &f(const int&a)

{

}

那么 f(3)可以.

int &f( int&a)

{

}

f(3)错误.


函数调用时形参是实参的拷贝.

同样考虑返回值.不能返回局部变量,而只能返回到一个临时变量中.

临时变量的值可能被丢弃,或者保存到一个生存期更长的变量中.


从汇编讲.

调用时将参数压入栈顶,     ========           将实参拷贝到形参.

返回时     将返回值放到栈顶   ======          将返回值放到临时变量

返回后,栈指针恢复,但栈顶的临时变量仍在, 此时可将其拷贝到一个生存期更长的变量中.


struct o{
    int x;
    int y;
};
o f(){
    int i=0;
    int j=1;
    o o1={30};
    int k=2;
    int l=3;
    return o1;
};
将创建两个o对象.一个是o1,一个是在栈顶创建返回的临时变量.
s foo(){
    int i=0;
    int j=1;
    int k=2;
    int l=3;
    printf("foo returns\n");
    return o(44,55);
};
将只创建一次o对象.

o o2=f(); // 调用f函数,系统会在运行时栈上开辟一数据结构的内存(活动记录),同时指针指向了该活动记录。

该活动记录中存放有函数返回的地址和返回值、局部变量等数据成员。
当函数返回时,系统会pop该活动记录,但这仅是“逻辑”上的删除,物理上数据还在那,在回到Main数时,还是可以访问返回值的。

return value optimization (RVO) 因为你在return时才会创建这个对象 那么这个对象在这个函数体内就不会再被使用了

编译器可以直接用那个临时变量的空间创建这个对象 不需要再额外多创建一份.


Mytime operator *( double i ) const    // 生成临时对象
//编译器会产生临时对象,并且调用拷贝构造函数初始化,执行完这个语句后,临时对象自动释放。
//所以产生临时对象有构造和析构的时间开销。

Mytime& operator *( double i ) const   // 不生成临时对象


一般对于拷贝构造函数,可以想像,不应该能修改被拷贝的对象.因此要求输入参数是const &,

如果拷贝构造函数的输入参数是一个临时对象呢?

如果被拷贝对象拥有大量资源,那么可见返回的对象也需要拥有相应的资源.

如果被拷贝对象在被拷贝后,就不存在了,那么它就需要随后释放相应的资源.

显然如果能把其拥有的资源直接移动交换给返回的拷贝对象,

而不是一方面对拷贝对象重新分配资源,而被拷贝对象又马上释放资源,能大幅提高效率.


那么拷贝构造函数的输入参数到底能否被修改,与输入参数是否是临时的右值对象有关.

需要两种不同的拷贝构造函数.

那么可以根据输入参数是否是临时的右值对象,进行重载处理.

输入参数是右值引用,表示其是临时的右值对象,可以被修改..

输入参数是const 左值应用,表示其不能被修改.

编译器根据输入参数的类型,选择合适的函数调用.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多