首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 虚析构函数
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • airsong_wjs
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 结帖率:
    发表于:2008-11-06 16:16:38 楼主
    关于虚析构函数的一个疑问:
    #include <iostream.h>
    class Base
    {
    public:
        virtual ~Base() { cout < < "~Base" < < endl ; }
    };
    class Derived : public Base
    {
    public:
        virtual ~Derived() { cout < < "~Derived" < < endl ; }
    };

    void main(void)
    {
        Base * pB = new Derived; // upcast
        delete pB;
    }

    输出结果为:
          ~Derived
          ~Base

    问题是:
    如果析构函数不为虚,输出结果为:
          ~Base


    请问这是为什么?这与析构的次序问题有什么本质的区别?

    50  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • fallening
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 16:17:391楼 得分:0
    看书吧,这个问题很基本的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • henry3695
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 16:28:002楼 得分:0
    如果析构函数不为虚,输出结果为:
          ~Base


    LZ你是如何让析构函数不为虚呢
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • bluecll
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 16:28:123楼 得分:0
    如果析构函数不为虚,说明delete pB的时候基类的析构函数就不会去调用派生类的析构函数,
    那么pB中将只有基类对象部分被删除,而派生类对象部分得不到删除。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhuwanglove
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 16:33:284楼 得分:0
    引用 3 楼 bluecll 的回复:
    如果析构函数不为虚,说明delete pB的时候基类的析构函数就不会去调用派生类的析构函数,
    那么pB中将只有基类对象部分被删除,而派生类对象部分得不到删除。

    同意3楼.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Longinc
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 16:35:175楼 得分:0
    不为虚函数时程序会崩溃的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • henry3695
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 16:37:486楼 得分:0
    基类的析构函数都需要设置为虚函数的吧
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ckt1120
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 16:39:547楼 得分:0
    可参考
    http://blog.csdn.net/starlee/archive/2006/03/09/619827.aspx
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jia_xiaoxin
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 21:40:258楼 得分:0
    如果析构函数不为虚,那么在
    Base * pB = new Derived; // upcast
    中,基类指针在delete时只会调用基类的析构函数,
    如果为虚析构函数,基类指针在delete时先调用派生类的析构函数,然后再调用基类的析构函数
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lann64
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 21:47:479楼 得分:0
    跟次序无关,因为你用的是基类指针,非虚析构函数,没有动态绑定过程,就只调用基类的析构。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zmlovelx
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 21:53:2810楼 得分:0
    析构函数不为虚
    则由 Base * pB 的静态类型决定调用 pB为Base*则调用 的是~Base

    如果析构函数为虚的话
    在类中会多生成一个虚表指针vptr 指向虚函数表 虚函数表中存放虚函数地址
    这时,调用的时候会根据pB指向的对象的this指针查找虚函数表中对应的虚函数地址,此例为~Derived
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • icerhack
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 21:59:5811楼 得分:0
    析构函数不为虚,在释放内存空间得时候,就会不释放派生类得内存,造成内存泄露
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zmlovelx
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 22:28:1312楼 得分:0
    http://topic.csdn.net/t/20021216/12/1264980.html
    http://topic.csdn.net/t/20061102/19/5129121.html
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • BaihowFF
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 23:00:0913楼 得分:0
    析构函数不虚...没办法实现多态的...这也是个基本问题...
    没有虚析构函数...对象无法正常析构...没办法找到到底用父类还是子类的析构...
    详细内容就看看书看看上面的连接吧...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hqin6
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-06 23:39:1514楼 得分:0
    上面都说了,我就jf了~~~~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • fableboy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 00:08:5115楼 得分:0
    up!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • q368160666
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 08:46:5816楼 得分:0
    Up!Up!!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • nk_ysg
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 09:04:2217楼 得分:0
    学习
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • chenhuaichao314
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 09:18:5218楼 得分:0
    同意3楼!
    up!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • holidiess
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 09:29:2219楼 得分:0
    up
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • vk2211
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 09:46:1920楼 得分:0
    这就是虚拟析构函数的作用
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lily604
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 10:14:3321楼 得分:0
    Base * pB 因为pb是基类型的,如果析构函数不是虚函数,那么就调用基类的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • redleaves
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 10:20:2822楼 得分:0
    引用 13 楼 BaihowFF 的回复:
    析构函数不虚...没办法实现多态的...这也是个基本问题...
    没有虚析构函数...对象无法正常析构...没办法找到到底用父类还是子类的析构...
    详细内容就看看书看看上面的连接吧...

    此言诧异....你还可以手工析构.比如加个Release.俺们COM都是这样搞的..
    当然,C++里用虚析构会方便得多...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dzc8866
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 10:31:1023楼 得分:0
    学习了UP
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • overbai
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 10:59:3624楼 得分:0
    析构函数不为虚
    则由 Base * pB 的静态类型决定调用 pB为Base*则调用 的是~Base

    如果析构函数为虚的话
    在类中会多生成一个虚表指针vptr 指向虚函数表 虚函数表中存放虚函数地址
    这时,调用的时候会根据pB指向的对象的this指针查找虚函数表中对应的虚函数地址,此例为~Derived

    正解!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhaohongbo83
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 11:01:2825楼 得分:0
    虚拟析构函数,传指针,调用子类析构函数,再析构基类
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • BuleRiver
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 14:28:0926楼 得分:0
    个人觉得这个才是C++多态的本质,运行时绑定到具体的函数,因为是虚析构函数,所以到运行的时候,会绑定到具体的类,然后运行相应的虚构函数,如果非虚,则只运行基类的构造函数。
    这个在基类是抽象类(接口类)的时候非常重要!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • xxgamexx
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-07 16:04:2227楼 得分:0
    LZ可能提了2个问题

    1,Base 的virtual 与Devived 中的virtual问题

    2, Base *a=new Devived;
      与Devived *a=new Base;的区别了。
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved