⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄.上一篇回顾到为什么要返回引用的问题,这里接着继续
---------------------------------------------------------------------------------------------------------------------
(1)首先是为什么不能返回一个临时对象的引用。
举个栗子:
class Test { public: Test(int a=10):ma(a) { cout<<"Test(int)"<<endl; } ~Test() { cout<<"~Test()"<<endl; } Test(const Test &src):ma(src.ma) { cout<<"Test(const Test&)"<<endl; } // public 真inline Test& operator=(const Test &src) { cout<<"Test& operator=(const Test &src)"<<endl; ma = src.ma; return *this; }//为什么要返回引用上一篇说过 int GetValue(){return ma;} private: int ma; }; Test& GetObject(Test &t) { int value = t.GetValue(); int buffer[1024]={0}; Test tmp(value); return tmp; } int main() { Test t1(20); Test t2; t2 = GetObject(t1); cout<<t2.GetValue()<<endl; return 0; }
上面的操作试图返回一个局部变量,于是编译器发现并给予警告。
那么执行这个程序会怎样呢
哎哎哎?.?好像也没错
于是换了个栗子继续测试
char *Get() { char arr[]="hello"; return arr; } int main() { Test t1(20); Test t2; t2 = GetObject(t1); //cout<<t2.GetValue()<<endl; char *p = Get(); printf("%s",p); return 0; }
终于如愿以偿的错了
局部变量的生存周期在函数体内,离开函数它就不存在了。那这个不存在指的是什么呢?
通过上面的例子可以发现数据并没有回收。回收的只有内存。
(ノ・ω・)ノ゙ 其实这个过程是这样的,每调用一个函数会在main栈帧之上开辟栈帧,
函数结束时栈帧回退地址收回,但是数据还是上面的!
这个时候再调用一个新函数,又会在main栈帧之上开辟栈帧并初始化,
如果足够大,之前的数据是可以被覆盖掉的!所以不能返回局部变量的引用。
---------------------------------------------------------------------------------------------------------------------
(2)接收返回值为对象的函数调用时,按初始化方式接收
Test GetObject2(Test &t) { int value = t.GetValue(); return Test(value); } int main() { Test t1(20); Test t2 = GetObject2(t1); cout<<t2.GetValue()<<endl; return 0; }
---------------------------------------------------------------------------------------------------------------------
(3)函数返回对象的时候优先返回一个临时对象(前篇有说)
Test GetObject3(Test &t) { int value = t.GetValue(); return Test(value); } int main() { Test t1(20); Test t2; t2 = GetObject3(t1); cout<<t2.GetValue()<<endl; return 0; }
-------------------------------------------------
=L=以上,纯属废话 不过好记性不如烂笔头 先记着
求保存的时候不要再改我格式了