分享
 
 
 

Bruce Eckel vs Stanley B Lippman.Who Is New Fresh?

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

2005.7.23

Written by smonster

China University of Geosciences (CUG)

Wuhan, Hubei Province

事情的起因:

最近要面试Autodesk,所以在网上到处搜刮“面经”,不巧真给我找到不少。而其中又已白云黄鹤的idoloveyou较全面,而且时间也比较近,因而便欣然阅记下来。有几段原话是这样的:

1.问:一般在什么时候构造函数被声明成private呢?

1.答:比如要阻止编译器生成默认的copy constructor

2.问:什么时候编译器会生成默认的copy constructor

2.答:只要自己没写,而程序中需要,都会生成

3.问:如果你已经写了一个构造函数,编译器还会生成copy constructor吗?

3.答:会

其它暂略。

事情的进展:

初看之下,看不出什么端倪,更何况我等粗人。本就不甚了了,对此一知半解,自是深信不疑。对比后面的各位大虾、牛人的若干修正,懵懵懂懂就把这些硬记下来了。但随着时间的一天天走过,自己也慢慢的把c++ primer翻来覆去,开始想一些较底层的东西,关心编译器的一些细节(没办法,谁让Lippman就喜欢这个调调呢?)。Primer574-575:

当我们写:Account acct2( acct1 );

编译器判断是否为Account类声明了一个显示的拷贝构造函数。如果声明了,且可访问,则调用它。如果没有声明拷贝构造的函数的实例,则执行缺省的按成员初始化。这里即是指primer上文提到的default memberwise initialization。即:一个类对象向该类的另一个类对象作拷贝是通过依次拷贝每个非静态数据成员来实现的。这指的是一种行为,并没有调用什么函数,编译器更没有帮助生成什么函数。因而对于文章开头的第2个问题,2的回答显然有些“望文生义”了。因为他知道平时我们即使不写,Account acct2( acct1 )也是对的,因而他理解成为了编译器的自动帮忙。到这里,第3个问题的答案也浮出了水面,不管我们写不写构造函数,好像跟编译器自动生成copy constructor没啥关系?呵呵,答案应为:不会。

那么我们现在要转过头看看第1个问题了。很显然,原作者头脑中编译器的能力根深蒂固。默认二字是指我们提供一个,那么需要的时候编译器就调用这个,并不是说我们不提供,编译器会帮助我们提供一个。最多,默认可以作用到行为上,叫做默认行为,指导编译器完成一系列动作,但似乎也不包括生成一个函数这么伟大!况且第1个问题问的是构造函数被声明成private有什么意义?因此,我马上又翻书到构造函数那章,真是不看不知道,一看又要笑。竟然又引出了一堆惊天大秘密。

意外的收获:

primer573:新用户常常会错误地认为,如果不存在缺省构造函数,则编译器会自动生成一个缺省构造函数(注意:又来了!),并将其应用在对象上,以初始化类的数据成员。对于我们定义的Account类来说,这不是真的:系统既没有生成缺省构造函数也没有调用它。

编译器并没有我们想象的那样聪明和勤快,虽然它对于我们初学者来说确实很神奇,但不至于到无所不能的地步,甚至不能生成一个最简单的构造函数!这确实与我们的想象差异甚大,但确实是真的。好了,在离开主题之前,我先来试着解答第1个问题,private型的构造函数用意应该在于阻止此类被实例化,其派生类也不行,当然友元除外。(更为专业的回答请见:primer 574)

总结来说,编译器不会替我们创建任何函数,构造函数、拷贝构造函数都不行。但没有生成函数并不代表编译器什么也没做,它有默认的(或称为缺省得)行为,比如memberwise initialization等等。它会尽量帮助我们渡过难关,而不是让我们去死,这就是我们为什么经常什么也没写,但程序又不出错的原因。好了,到了这,接下来的事很自然就发生了,我将自己的这一发现逐个告诉周围的朋友、同学,大大的炫耀了一番:)正在我得意洋洋的时候,居然意外的事又发生了,真是一波未平一波又起了!小心才能使得万年船啊~

峰回路转时:

一个同学当即对我得出如此论调提出了质疑:编译器所干的事情是通过函数来实现的。比如我们没有写Account::Account(){...};编译器会自动创建一个空Account()构造函数,而后什么也不干。对于copy constructor也一样,它会创建一个,并且会写上类似的this->obj1 = acct1.obj1等语句以完成赋值。这实在是太不可忍受了,我决不允许刚刚到手的知识就这样被别人侮辱(我的99%的C++知识来源于primer,于我似圣经)。正是大家争吵不休,面红耳赤之际,他搬来了C++领域内的另一经典著作Thinking in C++。第67页,以下是原话“缺省的构造函数是如此重要,所以在一个构造类型(struct或class)中没有构造函数时,编译器会自动创建一个。”............此时此刻,我的大脑中出现了一个唯一可以出现的口头禅“SHIT!!”

按图索骥,马上翻到介绍缺省的拷贝构造函数那一节,第187页:“因为拷贝构造函数实现传值方式的参数传递和返回,所以在这种简单结构情况下,编译器将有效的创建一个缺省拷贝函数,这非常重要”、“当包括更复杂的类型时,如果没有创建拷贝构造函数,C++编译器也将自动的为我们创建拷贝构造函数。”

草草收场:

当两本巨著相撞,当两位巨人相遇,受害的永远是我们这种本已什么就不懂得人。若不是为了这次面试,我绝不会去深究到底编译器是怎么工作的?它在背后默默的干了哪些对我们有益的事?又有多少有害的?也许有牛人会说这种争执毫无疑义,因为两位大师解释的最终结果是一致的(我这里可能没有列出来),只是实现的步骤不同(是不是创建了不为人知的构造函数)。

确实,这世界上能有多少事能够说得清清楚楚?又有多少BT的问题能得到完美的结果?做人苛求太多,就是跟自己过不去啦~~我对这个问题的最终定论是这样的:依赖于特定的编译器实现。注意,这是唯一不同时违背两大巨著,而又能行得通的答案。问题有答案了,但这算漂亮吗?完美吗?能得到认可吗?了结了吗?可以安心睡觉了吗?不得而知。只有一点个人期望,各位面试官能放我一马,活着压力已经够大了,何必非要加码?

不自觉有点愤青了...

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有