#include "stdafx.h"
#include<iostream>
#include<ostream>
#include<istream>
int& rref()
{
int i = 11;
return i;
}
int* rpot()
{
int j = 33;
return &j;
}
int _tmain(int argc, _TCHAR* argv[])
{
int &a = rref();
int *b = rpot();
std::cout<<"ref "<<a<<'\n';
std::cout<<"pot"<<*b<<'\n';
int c(2);
std::cin>>c;
return 0;
}
如以上两个函数rref,rpot,分别返回指向局部变量的引用和指针。
如果在测试时,_tmain只有函数rref
int &a = rref();
std::cout<<"ref "<<a<<'\n';
结果为ref11正确
如果_tmain只有函数rpot
int *b = rpot();
std::cout<<"pot"<<*b<<'\n';
结果为pot33正确
但是如果同时出现
int _tmain(int argc, _TCHAR* argv[])
{
int &a = rref();
int *b = rpot();
std::cout<<"ref "<<a<<'\n';
std::cout<<"pot"<<*b<<'\n';
int c(2);
std::cin>>c;
return 0;
}
结果为
ref 33
pot1834244
出现错误。
逐步调试程序,
当程序运行到
int *b = rpot();
此时a为11正确。
但是当运行到
std::cout<<"ref "<<a<<'\n';
a = 33
b = 0x0030f914
运行到
std::cout<<"pot"<<*b<<'\n';
*b = 3209748
a = 3209748
通过更改函数rpot中j的值,可以看出当程序运行到
std::cout<<"ref "<<a<<'\n';
本来引用i的引用a却引用了 j 的值。
当函数返回引用时,没有复制返回值,而是返回对象本身。
返回引用的函数返回一个左值,这样的函数可以用在任何要求使用左值的地方。
不要返回局部变量的引用或指针,因为一旦函数结束,局部变量被释放,对局部变量的引用会指向不确定的内存,返回的指针变成了悬垂指针。
出现上述错误的原因很可能是因为调用rref结束后,分配给局部变量i的存储空间被释放,此时对局部对象的引用即a指向不确定的内存,在本程序中a仍指向这个内存。
当调用rpot时,因为局部变量i的存储空间被释放,该存储空间分给了局部变量j,此时值为33,所以运行
std::cout<<"ref "<<a<<'\n';
时,a为33.
但是接下来运行
std::cout<<"pot"<<*b<<'\n';
的结果无法解释。
请问两者直接是如何影响的?
如果是类的话会不会出现同样情况?
在《More effective c++》一书中,介绍vitual copy constructor时,派生类成员函数返回了局部变量的指针
virtual FirstCom * getCopy() const{
return new FirstCom(*this);
}