首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

口试集锦-函数的按引用返回与按地址返回

2012-09-20 
面试集锦--函数的按引用返回与按地址返回函数按引用返回常见的一个错误:先来看一个错误代码:#includeiost

面试集锦--函数的按引用返回与按地址返回

函数值按引用返回常见的一个错误:

先来看一个错误代码:

#include<iostream>using namespace std;class A{private:int a;public:A(int num):a(num){cout<<"构造函数!"<<endl;}A(A &b){a=b.a;cout<<"复制构造函数!"<<endl;}~A(){cout<<"析构函数"<<endl;}void Setkey(int num){a=num;}int GetKey(){return this->a;}};//按引用返回,但是a是局部变量,因此超出fun函数作用域之后//a就消失了,所以b是一个不存在的对象的别名,所以程序输出随机数A&fun(){A a(3);return a;}int main(){A &b=fun();cout<<b.GetKey()<<endl;return 0;}

该代码输出随机数字,而不是3,原因如代码中注释所说,按引用返回,但是a是局部变量,因此超出fun函数作用域之后a就消失了,所以b是一个不存在的对象的别名,所以程序输出随机数
我们可以做如下修改:去掉A&fun()中的&:

#include<iostream>using namespace std;class A{private:int a;public:A(int num):a(num){cout<<"构造函数!"<<endl;}A(A &b){a=b.a;cout<<"复制构造函数!"<<endl;}~A(){cout<<"析构函数"<<endl;}void Setkey(int num){a=num;}int GetKey(){return this->a;}};//函数按值返回,必定会调用类的复制构造函数构造一个对象a的副本//在main函数中定义一个对象作为副本的别名,而对于引用而言,如//果引用的是一个临时变量,那么这个临时变量的生存期不少于引用的//生存期。也就是说main函数中的副本会在b这个别名生存期结束//之后才消失。A fun(){A a(3);return a;}int main(){A &b=fun();cout<<b.GetKey()<<endl;return 0;}


函数的输出结果是:

构造函数!
复制构造函数!
析构函数
3
析构函数
请按任意键继续. . .

正如代码中的注释所说,

函数按值返回,必定会调用类的复制构造函数构造一个对象a的副本在main函数中定义一个对象作为副本的别名,而对于引用而言,如引用的是一个临时变量,那么这个临时变量的生存期不少于引用的生存期。也就是说main函数中的副本会在b这个别名生存期结束之后才消失。

 

下面看一个利用按引用返回和按地址返回来解决内存泄露的问题:

#include<iostream>using namespace std;class A{private:int a;public:A(int num):a(num){cout<<"构造函数!"<<endl;}A(A &b){a=b.a;cout<<"复制构造函数!"<<endl;}~A(){cout<<"析构函数"<<endl;}void Setkey(int num){a=num;}int GetKey(){return this->a;}};void fun(A &a){a.Setkey(99);}int main(){A *b=new A(23);fun(*b);cout<<b->GetKey()<<endl;delete b;return 0;}


热点排行