Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6087627
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: C/C++

2013-07-02 02:16:21

原文地址:C++之virtual析构函数 作者:scq2099yt

        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析构函数。
        
        
        



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