这是否会导致内存泄漏/我应该如何构造代码

use*_*566 1 c++ inheritance memory-leaks

我有点担心这段代码可能有内存泄漏.我想知道实际上是否有泄漏,以及解决这个问题的正确方法是什么.

说明:我有一个基类Pet与派生类Cat,DogBird.我正在解析文件中的行,并且根据该行中的某些内容,我需要创建派生类的实例,然后以特定方式再次解析行的一部分.这是一个示例文件:

Dog Spot Brown,Labrador,5
Cat Felix Black,7
Bird Polly Green,Parrot,12,Crackers
Run Code Online (Sandbox Code Playgroud)

还有一些代码:

class Pet
{
protected:
  string _type;
  string _name;
  string _desc;

public:
  Pet();
  bool ParseLine(std::string line);
  string Type() { return _type; }
  string Name() { return _name; }
  string Desc() { return _desc; }
};

class Dog : public Pet
{
private:
  string _color;
  string _type;
  int _age;

public:
  Dog(string type, string name, string desc);
  bool ParseDesc(string desc);
};
Run Code Online (Sandbox Code Playgroud)

主要代码:

ifstream infile(filename, ifstream::in);
string line;
while(getline(infile, line))
{
   Pet* pet = new Pet();    // "new" called once
   if(pet->ParseLine(line))
   {
      if(pet->Type() == "Dog")
      {
         pet = new Dog(pet->Type(), pet->Name(), pet->Desc());   // "new" called again
         pet->ParseDesc(pet->Desc());
      }
      else if(pet->Type() == "Cat")
      {
         // ...
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

基本上会发生这样的事情:

我从文件中取一行并将其解析为三个字段(这是做什么的ParseLine():

Type (Dog, Cat, Bird, etc.)
Name (Spot, Felix, Polly, etc.)
Description ("Brown,Labrador,5", "Black,7", "Green,Parrot,12,Crackers", etc)
Run Code Online (Sandbox Code Playgroud)

然后我将这三个字段分配给我的Pet*变量.
然后,根据值Pet*->Type(),我解析Pet*->Desc()以获得该特定类型动物的附加信息.

我担心两次调用操作符"new".我认为可能有一种更好的方法来格式化可以完全避免这种情况的代码.

我真的想保持我的getline()日常生活.我不想查看该行以确定类型,然后决定如何创建我的实例.

此外,_type, _name, and _desc当我重新创建时,我必须重新分配我的变量Dog(),而我宁愿不必这样做.

谢谢.

-

具体来说,我该如何避免这种情况:

Pet* pet = new Pet();
pet->ParseLine(line);
string type = pet->Type();
string name = pet->Name();
string desc = pet->Desc();
delete pet;
if(type == "Dog")
{
   Pet* dog = new Dog(type, name, desc);
   dog->ParseDesc(desc);
}
Run Code Online (Sandbox Code Playgroud)

Con*_*ius 8

是的,这会导致内存泄漏,因为您分配了一个new Pet()永远不会删除的内容,并且使用new Dog()其他内容覆盖指向它的指针.

我建议你创建一个所谓的工厂函数,它从文件中读取一行,并创建Pet行状态的类型.