关于effective C++的条款9~~~

飞翔的土豆 2010-02-03 10:24:56
梅耶讲:绝不在构造和析构函数中使用虚函数。即便使用了虚函数也不会带来预想的效果。
我直观理解为virtual函数在构造函数中相当于变成了普通的非虚函数。
我想问的是之所以出现这种“虚函数在构造函数中失效”的现象,是设计虚函数表自然而然产生的后果?还是说为了避免出现条款9中讲的那些不合理的情况,而额外针对构造函数的特别设计?
...全文
371 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
windsting 2010-02-05
  • 打赏
  • 举报
回复
推荐看《Thinking in C++》(第二版第一卷)的相关章节,
这是我读过的书,关于这个问题讨论最透彻的一本,
里面还告诉你怎么在构造和析构里面实现虚调用。
我忘了第几章,但你看到那两节的题目就知道是它了。
Kinloloy 2010-02-04
  • 打赏
  • 举报
回复
受益匪浅啊~~好
飞翔的土豆 2010-02-03
  • 打赏
  • 举报
回复
感谢LS高人!!受益匪浅!
xylicon 2010-02-03
  • 打赏
  • 举报
回复
是的,我是这个意思,更具体些说是,在基类的构造函数中vptr指向是基类的虚函数表。其他函数就按照对象本身vptr了。

有兴趣可以看看这个。很有趣的例子。正好说明这个问题。

http://www.codeguru.com/cpp/com-tech/atl/tutorials/article.php/c3545
飞翔的土豆 2010-02-03
  • 打赏
  • 举报
回复
请问10L,是否是说对象的基类部分构造完之前,vptr所指的是基类的虚函数表,等到构造子类部分是,子类构造函数修改了vptr使其指向了派生类的虚函数表??
xylicon 2010-02-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 r06041210 的回复:]
先感谢LS的解答,但自己仍无头绪,可能我问题描述的不清楚~~
在构造函数中调用虚函数的效果我已经验证,为什么应该出现这种效果我也理解了,我不明白的是这种结果是怎么出现的。。。是虚函数机制本来就可以保证这一效果?还是说虚函数在构造函数中调用会发生问题,于是额外有了一种机制,使虚函数在构造函数中变为非虚函数?
[/Quote]

这是基类的构造函数 做了虚表(vtable)的调整导致的。也就是说,构造函数中的this指针指向的虚表是自己的虚表。



飞翔的土豆 2010-02-03
  • 打赏
  • 举报
回复
7L的话让我有了点想法,不过条款9中上来一段梅耶就讲:“JAVA和C#程序员更要注意本条,因为这是C++与它们不相同的地方”。。。
飞翔的土豆 2010-02-03
  • 打赏
  • 举报
回复
先感谢LS的解答,但自己仍无头绪,可能我问题描述的不清楚~~
在构造函数中调用虚函数的效果我已经验证,为什么应该出现这种效果我也理解了,我不明白的是这种结果是怎么出现的。。。是虚函数机制本来就可以保证这一效果?还是说虚函数在构造函数中调用会发生问题,于是额外有了一种机制,使虚函数在构造函数中变为非虚函数?
ZangXT 2010-02-03
  • 打赏
  • 举报
回复
设计抉择吧。
java语言中,构造函数中调用方法就可以有多态现象产生。
cattycat 2010-02-03
  • 打赏
  • 举报
回复
对,还是构造函数顺序的问题。先构造基类,然后子类。如果基类的构造函数中调用子类的构造函数,此时子类还没初始化完会出错。
Dolphin_001 2010-02-03
  • 打赏
  • 举报
回复
你还是看2楼的解释吧,很清晰
xylicon 2010-02-03
  • 打赏
  • 举报
回复
构造子类的时候先构造基类,基类构造的时候,子类还没创建出来,所以在基类中使用虚拟函数来调用子类的相应的函数是无意义的。

同理,析构的时候,子类已经先析构了,也不能使用虚函数实现多态。
Dolphin_001 2010-02-03
  • 打赏
  • 举报
回复
构造函数和析构函数内,已经可以确定是在本类中执行了,用虚函数反而变复杂了,但并不实效。
stardust20 2010-02-03
  • 打赏
  • 举报
回复
当基类的构造函数调用一个virtual函数时,不调用覆盖函数
例如,假如Derived类覆盖一个继承的virtual函数f(),而且Base::Base()调用f()。由于在Base::Base()的执行期间对象是一个Base,所以应调用Base::f()。假如C++允许Base::Base()调用Derived::f(),那么Derived::f()就可能调用还没构造的成员对象上的成员函数。
同样,当基类的析构函数调用一个虚拟函数时,也不调用覆盖函数
所以在构造或者析构函数中调用虚拟函数时,最好指出它所属的类如Base::Base();
a_rockboy 2010-02-03
  • 打赏
  • 举报
回复
和基类与子类的初始化顺序有关吧。基类初始化时,子类的数据成员尚未初始化,就算能调用子类的虚函数,也会产生无法预测的错误。
有人说c++程序员可以分成两类,读过effective c++的和没读过的。世界顶级c++大师scott meyers成名之作的第三版的确当得起这样的评价。当您读过这本书之后,就获得了迅速提升自己c++功力的一个契机。.(2-1)   在国际上,本书所引起的反响,波及整个计算技术出版领域,余音至今未绝。几乎在所有c++书籍的推荐名单上,本书都会位于前三名。作者高超的技术把握力、独特的视角。诙谐轻松的写作风格、独具匠心的内容组织,都受到极大的推崇和仿效。这种奇特的现象,只能解释为人们对这本书衷心的赞美和推祟。《effective c++》前两个版本的确抓住了全世界无数程序员的目光。原因十分显明:scott meyers 极富实践意义的c++ 研讨方式,描述出专家用以产出干净、正确、高效代码的经验法则和行事法则——也就是他们几乎总是做或不做的某些事。   这本书不是读完一遍就可以束之高阁的快餐读物,也不是用以解决手边问题的参考手册,而是需要您去反复阅读体会的,c++是真正程序员的语言,背后有着精深的思想与无与伦比的表达能力,这使得它具有类似宗教般的魅力。希望这本书自瞄帮助您跨越c抖的重重险阻,领略高处才有的壮美风光,做—个成功而快乐的c++程序员。...      本书一共组织 55 个准则,每一条准则描述一个编写出更好的 c++ 的方式。每一个条款的背后都有具体范例支撑。第三版有一半以上的篇幅是崭新内容,包括讨论资源管理和模板(templates)运用的两个新章。为反映出现代设计考虑,对第二版论题做了广泛的修订,包括异常(exceptions)、设计模式(design patterns)和多线程(multithreading)。      《effective c++》的重要特征包括:    * 高效的 classes、functions、templates 和inheritance hierarchies(继承体系)方面的专家级指导。    * 崭新的 "tr1" 标准程序库功能应用,以及与既有标准程序库组件的比较。    * 洞察 c++和其他语言(例如java、c#、c)之间的不同。此举有助于那些来自其他语言阵营的开发人员消化吸收 c++ 式的各种解法。(2-1)

65,199

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧