在哪里删除?

Luk*_*keN 0 c++ oop

我很难在这里决定删除派生类的最佳方法.我目前有以下布局:

class Tag {
   // Stuff
   // [...]
   void releaseMemory(Tag *t);
};

class TagByte : public Tag { /* [...] */ };
class TagShort : public Tag { /* [...] */ };

Tag::releaseMemory(Tag *t) {
    switch (t->getType()) {
       case TAG_BYTE:  delete (TagByte *)t; return;
       case TAG_SHORT: delete (TagShort *)t; return;
       // [...] many more
    }
}
Run Code Online (Sandbox Code Playgroud)

我这样做的原因是有更复杂的标签TagCompound,其中包含不同类型的标签,所有这些标签都存储为Tag *.在析构函数内部~TagCompound,~TagList我会调用Tag::releaseMemory();每个标记,因为delete在一个Tag *只会释放一个Tag而不是实际的TagWhatever,从而导致内存泄漏.

我想到的另一个选择是为每个派生类添加一个新的虚方法,因此每个子类Tag都拥有它自己releaseMemory()而不是超类中的一个组合.

然后我想知道我是否已经在设计级别上开始变坏,假设所有内容都传递到复杂类型TagCompound并且TagList是一个对象,我也找不到更好的解决方案,因为整个构造是解析器的一部分看起来像这样的东西(只是二进制而不是冗长):

TAG_Compound("Root"): 4 entries
{
  TAG_String("Name"): Test
  TAG_Short("SomeNumber"): 21
  TAG_Double("..."): 9000.5
  TAG_Compound("Eek!"): 2 entries
  {
    TAG_String("Marco"): Polo
    TAG_List("Names"): 3 entries of type String
    {
      TAG_String: Hello
      TAG_String: World
      TAG_String: Segfault
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

并且在运行时动态读取它并不能很好地与堆栈上的实例一起使用.

我能做些什么......我不知道......优雅?

Ben*_*igt 5

通常,您只需在基类中声明一个虚拟析构函数.这对堆栈和堆分配都很好.在多态删除的情况下,编译器会计算出真实类型并调用其析构函数.