Мне довольно трудно выбрать лучший способ удалить мои производные классы здесь.В настоящее время у меня есть следующий макет:
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
}
}
Причина, по которой я это делаю, состоит в том, что существуют более сложные теги, такие как 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
}
}
}
И динамическое чтение этого во время выполнения не очень хорошос экземплярами в стеке.
Что я могу сделать, чтобы сделать это ... Я не знаю ... элегантно?