2 回答
TA贡献1785条经验 获得超4个赞
我来回答你的问题,很简单,你的代码需要修改为:
#include <iostream>
using namespace std;
class A
{
public:
A(int i){cout<<"构造函数执行\n";x=i;}
A(A&a){cout<<"复制构造函数创建对象\n";x=a.x;}
~A(){cout<<"析构函数\n";}
int get()const{return x;} //因为第22行代码A&r=&func();改为了const A&r=func();此处必须加const。
private:
int x;
};
A func()
{
cout<< " 跳转到func函数中"<<endl;
A a(23);
cout<<"a 的地址"<<&a<<endl;
return a;
}
int main()
{
const A&r=func(); //r是一个类A的引用,func()函数返回的是一个类A的对象,不是指针,func()函数前不要&。引用必须和对象绑定,不能和数值或计算式绑定,否则要加const。(早期的编译器如:VC++6.0可以写成A &r=func(),现在的编译器都不支持)
cout<<r.get()<<endl;//r不是指针,要改成r.get()
cout<<"a 的地址"<<&r<<endl;//r是一个类A的引用,输出r地址应改为&r
system ("pause");
return 0;
}
最后回答你func()函数返回的是一个临时对象,为什么“cout<<r.get()<<endl;”还能得到23?
因为对于引用而言,如果引用的是一个临时变量,那么这个临时变量的生存期会不小于这个引用的生存期(可参见C++标准[class.temporary])。也就是说,直到main函数结束时,引用r的生存期才结束,所引用的临时变量的生存期也才结束。
需要特别说明的是以上代码在Dev c++和vs2017的运行结果是不一样的。vs2017会调用复制构造函数,func()函数返回的是对象a的副本;Dev c++不会调用复制构造函数,func()函数返回的是对象a本身。
TA贡献2021条经验 获得超8个赞
稍微修改了你的代码,得到了正确的结果
#include <iostream>
using namespace std;
class A
{
public:
A(int i){cout<<"构造函数执行\n";x=i;}
A(A&a){cout<<"复制构造函数创建对象\n";x=a.x;}
~A(){cout<<"析构函数\n";}
int get(){return x;}
private:
int x;
};
A* func()
{
cout<< " 跳转到func函数中"<<endl;
A* a = new A(23);
cout<<"a 的地址"<<&a<<endl;
return a;
}
int main()
{
A* r = func();
cout<<r->get()<<endl;
cout<<"a 的地址"<<r<<endl;
system ("pause");
return 0;
}
按照你的改动,我的dev-cpp也还是不能编译,感觉这么改正规一点,函数返回值返回一个指针才能在后用执行->运算符吧
补充:
这里可能是调用了隐式的拷贝构造函数,因为你显式定义的拷贝构造函数不能完成A& r = func();这一句的拷贝构造。因此编译器为你隐式的定义了属于A& r = func();这种调用方法的拷贝构造函数。
另外a确实在函数局部被析构了,但这发生在return语句之后,return语句已经将a返回给了A& r,r.get()依然能返回23
- 2 回答
- 0 关注
- 298 浏览
添加回答
举报