Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5654671
  • 博文数量: 291
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7924
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 14:28
个人简介

阿里巴巴是个快乐的青年

文章分类

全部博文(291)

文章存档

2018年(21)

2017年(4)

2016年(5)

2015年(17)

2014年(68)

2013年(174)

2012年(2)

分类: C/C++

2013-06-30 14:46:08

        C++明确指出:当derived class对象经由一个base class指针被删除,而该base class带着一个non-virtual析构函数,其结果未定义——实际执行时通常发生的是对象的derived成分没被销毁,而base成分会被销毁,于是造成一个诡异的“局部销毁”对象,从而导致资源泄漏,比如:
        class base{
        public:
                base(){printf("base con\n");}
                ~base(){printf("base der\n");
                ...
        };

        class derived : public base{
        public:
                derived() {printf("derived con\n");}
                ~derived(){printf("derived der\n");}
                ...
        };

        int main()
        {
                base *b = new derived;
                delete b;
                return 0;
        }
        输出结果是:
        base con
        derived con
        base der
        解决这个问题方法很简单:给base class一个virtual析构函数即可,比如:
        class base{
        public:
                base(){printf("base con\n");}
                virtual ~base(){printf("base der\n");
                ...
        };

        class derived : public base{
        public:
                derived() {printf("derived con\n");}
                ~derived(){printf("derived der\n");}
                ...
        };

        int main()
        {
                base *b = new derived;
                delete b;
                return 0;
        }
        输出结果是:
        base con
        derived con
        derived der
        base der
        任何class只要带有virtual函数都几乎确定应该也有一个virtual析构函数,如果class不含有virtual函数,通常表示其并不意图被用作一个base class,此时,如果令其析构函数为virtual往往是一个馊主意,比如:
        class Point{        //一个二维空间点
        public:
                Point()(int x, int y);
                ~Point();
        private:
                int x;
                int y;
        };
        如果int占用32 bits,那么Point对象可塞入一个64 bits缓存器中,更有甚者,这个Point对象可被当做一个”64 bits量“传给C语言撰写的函数,然而当Point的析构函数是virtual时,对象体积发生变化,增加了32 bits的vptr,大小增至96 bits,而C语言中没有vptr,因此,也就无法传递了,除非明确补偿vptr,这样也就不再具有可移植性了。
        polymorphic(带多态性质的)base classes应该声明一个virtual析构函数。如果class带有任何virtua函数,它就应该拥有一个virtual析构函数。
        classes的设计目的如果不作为base classes使用,或不是为了具备多态性(polymorphically),就不该声明virtual析构函数。
        
        
        



阅读(3419) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

scq2099yt2013-06-30 14:46:24

文明上网,理性发言...