1.不要返回不在作用域内的引用
class TestSimple
{
public:
TestSimple()
{
cout << "TestSimple Constructor..." << endl;
};
TestSimple(TestSimple&);
~TestSimple()
{
cout << "TestSimple Destructor..." << endl;
};
void SetNum(int iNum)
{
num = iNum;
}
int GetNum() const
{
return num;
}
private:
int num = 5;
};
TestSimple & TheFunc()
{
TestSimple testSimple;
cout << &testSimple << endl;
testSimple.SetNum(12);
return testSimple;
}
int _tmain(int argc, _TCHAR* argv[])
{
TestSimple &rTestSimple = TheFunc();
cout << "rTestSimple Address:" << &rTestSimple << endl;
cout<<"rTestSimple.GetNum():"<<rTestSimple.GetNum()<<endl;
return 0;
}
输出:
TestSimple Constructor...
0033FA8C
TestSimple Destructor...
rTestSimple Address:0033FA8C
rTestSimple.GetNum():-858993460
请按任意键继续. . .
结论:显然rTestSimple与在函数TheFunc中创建的testSimple地址一样。但是testSimple已经不在作用域被析构了。因此该函数返回一个不在作用域的不存在的对象,是很糟糕的事情。
为了解决上面问题,我们试试让TheFunc函数内,创建堆中的对象,并返回,如下:
2.返回指向堆中对象的引用
class TestSimple
{
public:
TestSimple(){};
TestSimple(TestSimple&);
~TestSimple(){};
void SetNum(int iNum)
{
num = iNum;
}
int GetNum() const
{
return num;
}
private:
int num = 5;
};
TestSimple & TheFunc()
{
TestSimple *pTestSimple = new TestSimple();
pTestSimple->SetNum(12);
cout << "FunTestThree return!" << endl;
return *pTestSimple;
}
int _tmain(int argc, _TCHAR* argv[])
{
TestSimple &rTestSimple = TheFunc();
cout << "rTestSimple Address:" << &rTestSimple << endl;
cout << "rTestSimple.GetNum() :" << rTestSimple.GetNum() << endl;
TestSimple *pTestSimple = &rTestSimple;
cout << "pTestSimple Address" << pTestSimple << endl;
delete pTestSimple;
pTestSimple = nullptr;
cout << endl;
cout << "After delete pTestSimple" << endl;
cout << "rTestSimple Address:" << &rTestSimple << endl;
cout << "pTestSimple Address:" << pTestSimple << endl;
return 0;
}
输出:
FunTestThree return!
rTestSimple Address:0073D300
rTestSimple.GetNum() :12
pTestSimple Address0073D300
After delete pTestSimple
rTestSimple Address:0073D300
pTestSimple Address:00000000
请按任意键继续. . .
结论:看似返回的引用对象,能够输出Num的值,并且也能够Delete释放对象。但是在Delete对象以后,rTestSimple任然存在,但是此时的rTestSimple引用向的对象已经被释放了,rTestSimple还引用什么呢?(引用不能赋值NULL)
将函数改为返回指针,如下:
TestSimple * TheFunc()
{
TestSimple *pTestSimple = new TestSimple();
pTestSimple->SetNum(12);
cout << "FunTestThree return!" << endl;
return pTestSimple;
}
虽然这样能够在Main函数内很好的释放内存,并且没有无用的引用,但是最优的解决方案是:
分配内存的函数也负责释放内存。