为了账号安全,请及时绑定邮箱和手机立即绑定

下面这段代码在VC++中可以编译运行,为什么在Dev-c++不能编译运行?咋回事?

下面这段代码在VC++中可以编译运行,为什么在Dev-c++不能编译运行?咋回事?

C C++
哆啦的时光机 2022-11-04 16:13:24
#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(23);cout<<"a 的地址"<<&a<<endl;return a;}int main(){A&r=&func();cout<<r->get()<<endl;cout<<"a 的地址"<<r<<endl;system ("pause");return 0;}如果在func函数前面加上引用,A &func() devc++就可以编译了。可是a出去不是空引用么?怎么会得到a的值呢?A&r=func(); //这前面没有&cout<<r.get()<<endl; //这里不是指针 用的是"."cout<<"a 的地址"<<&r<<endl; //这里是&rsystem ("pause");return 0;cout<<r.get()<<endl; //这里不是指针 用的是"."cout<<"a 的地址"<<&r<<endl; //这里是&rsystem ("pause");return 0;
查看完整描述

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本身。


查看完整回答
反对 回复 2022-11-08
?
宝慕林4294392

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


查看完整回答
反对 回复 2022-11-08
  • 2 回答
  • 0 关注
  • 298 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信