喵宅苑 MewoGarden × 技术宅社区II | Z站 Z Station 棒棒哒纯文字二次元技术社区

正文

为什么用不同的软件输出结果会不同?

作者:樱花流逝
总之问题是这样的[mw_shl_code=applescript,true]#include<iostream> using namespace std; class point{ private: int x, y; public: point(int a = 0, int b = 0){ x = a; y = b; } point(point &p); int getx(){ return x; } int gety(){ return y; } }; point::point(point &p){ x = p.x + 10;[mw_shl_code=applescript,true]point::point(point &p){ x = p.x + 10; y = p.y + 20; cout << "调用拷贝构造函数" << endl; } y = p.y + 20; cout << "调用拷贝构造函数" << endl; } void f(point &p){ cout << p.getx() << " " << p.gety() << endl; } point g(){ point q(3, 5); return q; } int main() { point p1(2, 4); point p2(p1); cout << p2.getx() << " " << p2.gety() << endl; f(p2); p2 = g(); cout << p2.getx() << " " << p2.gety() << endl; system("pause"); return 0; } [/mw_shl_code] 用cb编译运行的得到的结果是这样的[attach]428336[/attach] 而用vs2013编译得到的结果是这样的[attach]428337[/attach] 虽然乱码也是问题。。。 但主要是为什么使用vs2013时在执行[mw_shl_code=applescript,true]p2 = g();[/mw_shl_code]时调用了 [mw_shl_code=applescript,true]point::point(point &p){ x = p.x + 10; y = p.y + 20; cout << "调用拷贝构造函数" << endl; }[/mw_shl_code] 而cb没有这一步?

回复

作者:Shino_Asada
[i=s] 本帖最后由 Shino_Asada 于 2015-10-4 13:52 编辑 point p2(p1); 这个调用是没问题的,因为p1是左值 会输出"调用拷贝构造函数" p2 = g(); g返回右值 point& 非const左值引用不能引用右值,所以不会调用你的拷贝构造函数 CB调用了编译器合成的拷贝构造函数,应该是这个样子的 Point::Point(const Point&); 你也看到了,p2.x和y和g返回的的point一样 拷贝构造函数不应该改变被拷贝对象,所以应该是》》》》const《《《《《 Point& VS的嘛……233333333嘛~至于f(p2); f接受的是Point& 所以不会发生拷贝 (小声:引用的底层实现一般是指针哟)
查看回复

作者:张全蛋
[i=s] 本帖最后由 张全蛋 于 2015-9-20 01:34 编辑 我已经在MSDN上看到了关于RVO(返回值优化)和NRVO(命名返回值优化)的介绍了,说白了你遇到的问题就是现代编译器为了提高程序运行效率优化搞出来的鬼。而在VS上,编译debug版会调用复制构造函数,但编译release版并不会,跟Devcpp的结果一样。
查看回复

作者:张全蛋
[i=s] 本帖最后由 张全蛋 于 2015-9-19 11:28 编辑
樱花流逝 发表于 2015-9-18 12:21 楼上那个是我自己 我的意思是按调用拷贝构造函数的规则,这段代码应该要调用三次,但vs只调用了两 ...
你可以搜下C++的返回值优化,这个优化程度跟编译器有关。CSDN论坛上有个类似的情况,里面的回复中应该能找到你想要的答案 http://bbs.csdn.net/topics/390803716
查看回复

作者:张全蛋
樱花流逝 发表于 2015-9-18 12:21 楼上那个是我自己 我的意思是按调用拷贝构造函数的规则,这段代码应该要调用三次,但vs只调用了两 ...
我那个VS2013调用了3次,Devcpp调用了2次。
查看回复

作者:樱花流逝
番茄星人 发表于 2015-9-17 00:11 原理上楼上已经说了。 至于为什么vs在p2 = g(); 会调用拷贝 我只能猜
楼上那个是我自己@@10!! 我的意思是按调用拷贝构造函数的规则,这段代码应该要调用三次,但vs只调用了两次,cb只调用了一次(还用一次应该是调用了但不知为何没有显示提示语句)。我想问的是这个。。。
查看回复

作者:樱花流逝
番茄星人 发表于 2015-9-17 00:11 原理上楼上已经说了。 至于为什么vs在p2 = g(); 会调用拷贝 我只能猜
楼上那个是我自己@@10!! 我的意思是按调用拷贝构造函数的规则,这段代码应该要调用三次,但vs只调用了两次,cb只调用了一次(还用一次应该是调用了但不知为何没有显示提示语句)。我想问的是这个。。。
查看回复

作者:番茄星人
原理上楼上已经说了。 至于为什么vs在p2 = g(); 会调用拷贝 我只能猜 类之间直接赋值会调用拷贝复制函数(PS:不是拷贝构造),也就是 = 的重载函数,前提是你重载了这个函数 明显你是没有重载的,所以至于这个重载的形态是什么,那应该由编译器来默认决定了。 所以有可能是在cb编译器上,它会帮你生成一个默认的拷贝复制函数 然而VS的编译器采用的策略则是,用你写的拷贝构造来当拷贝复制 以上纯属猜测,编译器那些东西要看手册才知道
查看回复

作者:樱花流逝
去查了一下调用拷贝构造函数的情形 在C++中,下面三种对象需要调用拷贝构造函数: 1) 一个对象以值传递的方式传入函数体; 2) 一个对象以值传递的方式从函数返回; 3) 一个对象需要通过另外一个对象进行初始化; 如果这样的话 point p2(p1); 第三条 f(p2); 第一条 p2 = g(); 第二条 应该要三次调用拷贝构造函数才对然而vs编译的只调用了两次,cb编译的应该也只调用了两次(第一次和第三次),如果第三次确实正确调用了的话应该会显示提示信息才对,但并没有显示orz
查看回复
上一页
下一页
0%
站点地图友情链接:
喵宅苑
喵空间社区程序
喵宅苑 静态版
宅喵RPG地图编辑器
络合兔
Lanzainc
技术宅
小五四博客
莉可POI
Mithril.js
枫の主题社
Project1
午后少年
机智库
七濑胡桃
xiuno
幻想の日常
魂研社
Nothentai
0xffff
欲望之花
泽泽社长
淀粉月刊
HAYOU
红客联盟
异次元
轻之国度
神奇宝贝新生代
游戏狗
口袋双子星
我的世界论坛
梦次元
动漫东东
动漫国际
精艺论坛
78动漫
吐槽弹幕网
漫客栈