如何避免内容泄漏多态和向量?

时间:2018-02-13 13:29:34

标签: c++ memory-leaks polymorphism c++98

早上好,

我正在开发一个使用多态的C ++应用程序,我想要一些建议以避免内存泄漏。 见下面的代码:

class IItem
{
public:
  IItem(){}
  virtual void Init() = 0;
  virtual ~IItem(){}
};

class ItemA : public IItem
{
private:
  int m_a;

public:
  ItemA(){ m_a = 0; }
  void Init(){m_a = 10;}
  virtual ~ItemA(){}
};


class Element
{
public:
  int m_a;
  int m_b;
  IItem* m_pItem;

  Element(){}
  void Init(IItem* item)
  {
    m_pItem = item;
  }
  virtual ~Element(){}
};

class ItemInfo
{
public:
  int m_id;
  std::string m_name;
  Element m_element;

public:
  ItemInfo(){}
  virtual ~ItemInfo(){}
};

class Test
{

public:
  Test(){}
  virtual ~Test(){}

void Initialize(std::vector<ItemInfo>* arrayItem)
{
    for(int i=0;i<5;i++)
    {
            arrayItem->push_back(ItemInfo());
            arrayItem->back().m_element.Init(new ItemA());
    }
 }
};

我正在使用这一行调用主程序:

Test test;
std::vector<ItemInfo> arrayItemInfo;
test.Initialize(&arrayItemInfo);

在函数Initialize中我正在使用&#34; new ItemA&#34;而我的问题是如何删除内存的属性?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

如果可以,请使用std::unique_ptr<>代替普通指针(*)

class Element
{
public:
  std::unique_ptr<IItem> m_pItem;

  Element(){}
  void Init(IItem* item)
  {
    m_pItem.reset(item);
  }
  virtual ~Element(){}
};

请注意,在此表单中,您的类变为不可复制(因为std :: unique_ptr已删除了复制语义)。如果这是一个限制,您可以:

(*)当然你需要使用new创建对象(就像你一样),因为std::unique_ptr的默认删除只是delete指针。如果您想要不同的行为,可以提供自定义删除。

如果您不能使用C ++ 11功能,最简单的方法是在析构函数中手动处理内存管理:

class Element
{
public:
  IItem* m_pItem;

  Element(IItem* item)
  : m_pItem(item)
  { }

  virtual ~Element()
  {
    delete m_pItem;
    m_pItem = NULL;
  }
};

class ItemInfo
{
public:
  int m_id;
  std::string m_name;
  Element m_element;

public:
  ItemInfo(IItem* item)
  : m_element(item)
  { }
  virtual ~ItemInfo()
  {}
};

我还更新了代码,通过构造函数而不是丑陋的Init/Release - 类似接口来使用初始化。现在,使用此代码,您的循环变得更好:

void Initialize(std::vector<ItemInfo>* arrayItem)
{
    for(int i = 0; i < 5; i++)
    {
      arrayItem->push_back(ItemInfo(new ItemA()));
    }
}

但是,请注意,您需要提供正确的复制语义,以避免多次删除同一个对象(或者只是禁用复制)。

另一种方法可能是查看std::auto_ptr<>,但由于它现在已被弃用(从C ++ 11开始),我建议避免使用它。

顺便说一下,virtual中的Element析构函数,您发布的代码中不需要ItemInfoTest类。