免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1837 | 回复: 9

[C++] C++多态下会存在内存泄漏? [复制链接]

论坛徽章:
0
发表于 2015-07-10 10:41 |显示全部楼层
源码如下:

class A{
     public:
            A() {printf("contrust A\n");};
            virtual void f() { printf("A::f \n");  }
            ~A() {printf("discontruct A \n");};
     private:
            int a;
};

class B:public A{
        public:
            B() {printf("contrust B\n");};
            virtual void f() {
                printf("B::f \n");
                b1 = new int[1];
            }
            ~B(){printf("discontruct B \n");delete b1;};
        private:
            int *b1;
};

int main(){
    A* b = new B();
    b->f();
    delete(b);
}


运行结果:
contrust A
contrust B
B::f
discontruct A


delete(b)并没有调用B类的析构函数,所以b1不会被释放,导致memory leak。这样理解是否正确?

论坛徽章:
323
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2015-07-10 10:43 |显示全部楼层
析构函数改成虚的

论坛徽章:
0
发表于 2015-07-10 10:47 |显示全部楼层
回复 2# hellioncu

大神详细讲一下,是因为虚函数表的原因吗?

   

论坛徽章:
12
2015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之同曦
日期:2017-03-17 19:13:162016科比退役纪念章
日期:2016-11-07 08:28:12luobin
日期:2016-06-17 17:46:36wusuopu
日期:2016-06-17 17:43:4515-16赛季CBA联赛之福建
日期:2016-01-14 12:49:22程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2015-06-08 22:20:00程序设计版块每日发帖之星
日期:2015-06-08 22:20:002015年亚洲杯之科威特
日期:2015-03-24 14:21:272015年迎新春徽章
日期:2015-03-04 09:57:092016科比退役纪念章
日期:2018-04-10 16:20:18
发表于 2015-07-10 11:05 |显示全部楼层
这种情况下,一般要把基类的析构写成虚函数,原因可以看看 《effective C++》。

论坛徽章:
5
金牛座
日期:2015-07-03 13:32:00卯兔
日期:2015-07-03 13:32:17程序设计版块每日发帖之星
日期:2015-11-29 06:20:0015-16赛季CBA联赛之同曦
日期:2015-12-15 09:36:06CU十四周年纪念徽章
日期:2016-07-06 17:18:48
发表于 2015-07-10 12:58 |显示全部楼层
我觉得f()的调用用到了多态,析构没用到多态吧。
A析构为虚函数,delete(b)的时候才能调用class B的析构,然后才会调用基类A的析构。

论坛徽章:
12
2015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之同曦
日期:2017-03-17 19:13:162016科比退役纪念章
日期:2016-11-07 08:28:12luobin
日期:2016-06-17 17:46:36wusuopu
日期:2016-06-17 17:43:4515-16赛季CBA联赛之福建
日期:2016-01-14 12:49:22程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2015-06-08 22:20:00程序设计版块每日发帖之星
日期:2015-06-08 22:20:002015年亚洲杯之科威特
日期:2015-03-24 14:21:272015年迎新春徽章
日期:2015-03-04 09:57:092016科比退役纪念章
日期:2018-04-10 16:20:18
发表于 2015-07-10 13:15 |显示全部楼层
回复 5# seanking1987


    我觉得你觉得的错了所以你还是别觉得了,书上说得很清楚。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-07-10 17:23 |显示全部楼层
回复 1# matchbox1224


    C++ 基本功啊

  1. struct A
  2. {
  3.     virtual ~A(){}
  4. };

  5. struct B, A
  6. {
  7.     virtual ~B(){}
  8. };
复制代码
如果某个类未来可能会被继承,把析构函数改成虚的

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2015-07-10 17:46 |显示全部楼层
回复 7# lost_templar

不一定哦,你看看COM里的那些interface,都没有virtual destructor哦……

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-07-10 22:15 |显示全部楼层
回复 8# windoze


    COM ………… 真的没有机会用,传说到时听了不少
    不用虚析构函数,在毁尸灭迹的时候是怎么清理派生类留下的蛛丝马迹的?

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2015-07-11 00:15 |显示全部楼层
回复 9# lost_templar

所有COM对象都能直接delete,你需要用一个virtual function,也就是Release()去减少引用计数,引用计数到0时这个函数就delete this

因为Release是个虚函数,所以它是具体类的,所以它能调用具体类的destructor,所以这个对象的destructor就不需要是虚函数了。

但缺点是每个COM对象都要自己实现一遍Release,内容还都是一样的……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP