构造析构中的虚函数

今天花了好长时间在项目中找到一个内存泄漏的bug,其根本原因是设计思想在作怪。犯了C++之兵家大忌,在析构中调用
 了虚函数。拿出来和大家分享一下~_~
 假设我们有这样的一个设计:
 class ItemContainBase   //存放元素的容器
 {
 public:

     ItemContainBase();
     virtual ~ItemContainBase();

     void Destory(void);    //销毁(主要是调用DestoryItems)
 
 protected:

     list<Item*> m_items;

 

 private:

 

     virtual void DestoryItems(); //销毁容器的元素(如果子类有自已的元素要销毁, 就要重写这个函数)
 }

 

 ItemContainBase::ItemContainBase()
 {

 }


 ItemContainBase::~ItemContainBase()   //这里希望通过多态实现所有子类通用的销毁操作
 {
     Destory();
 }

 void ItemContainBase::Destory(void)
 {
     DestoryItems();
    //do other thing here....
 }

 void ItemContainBase::DestoryItems(void)
 {
    //delete m_items's item
    for (list<Item*>::iterator iter=m_items.begin(); iter!=m_items.end(); ++iter)
    {
       if(*iter != NULL)
      {
         delete *iter;
      }
    }
 }

 

 class ItemWindowContain : public ItemContainBase //存放元素的窗口容器 
 {
 public:

    ItemWindowContain(){}       
    ~ItemWindowContain(){}       //在父类中已经用多态实现了销毁的操作,所有这里为空

 

  private:

 

  virtual void DestoryItems();     //重写父类的    
  list<Window*> m_itemWindos;      //主要是为元素动态生成窗口


 };

 void ItemWindowContain::DestoryItems()
 {
    ItemContainBase::DestoryItems();
    //delete m_itemWindos's item
    for (list<Window*>::iterator iter=m_itemWindos.begin(); iter!=m_itemWindos.end(); ++iter)
    {
       if(*iter != NULL)
       {
          delete *iter;
       }
    }
 }
 
 测试代码如下:
 ItemWindowContain* pWindowContain = new ItemWindowContain;
 delete pWindowContain;

 在析构的时候,结果会按照设计者的思想去销毁ItemWindowContain中的m_itemWindos和继承下来的
 m_items中的所有元素吗? 答案是否定的。在ItemContainBase的析构函数中并没有对DestoryItems
 进行多态的操作,它调用了自己的DestoryItems也就是ItemContainBase::DestoryItems. 这样悲剧就
 发生了,如果不停的使用new delete ItemWindowContain元素; 就会不停地内存泄漏. 同样的情况也会
 发生在构造函数中。
 如果你在开发过程中碰到了r6025 pure virtual function call的错误,那么你很可能就是用了上面的
 错误的设计思想. 在构造或析构函数中间接地调用了纯虚函数。
 所以得出一个结论: 绝不能在构造或析构函数中间接调用纯虚函数,也不要调用虚函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值