delete irregular
вызывает деструктор ~Irregular()
, который затем вызывает деструктор std::string::~string()
3 раза. Вызов этого, когда irregular
не является активным членом объединения, неопределенное поведение .
delete regular
вызывает деструктор std::string::~string()
1 раз. Вызов этого, когда regular
не является активным членом объединения, является неопределенным поведением .
Вам необходимо отслеживать, какой член объединения активен, чтобы вы могли вызвать соответствующий деструктор, например :
enum Verbform_type { vtIrregular, vtRegular };
union Verbform_data {
Irregular* irregular;
std::string* regular;
};
struct Verbform {
Verbform_type type;
Verbform_data data;
Verbform(Irregular irreg) {
type = vtIrregular;
data.irregular = new Irregular(irreg);
}
Verbform(std::string reg) {
type = vtRegular;
data.regular = new std::string(reg);
}
~Verbform() {
switch (type) {
case vtIrregular:
delete data.irregular;
break;
case vtRegular:
delete data.regular;
break;
}
}
}
Кроме того, не забывайте следовать правилу 3/5/0 , добавляя конструкторы копирования / перемещения и операторы копирования / перемещения.
В противном случае вам следует просто полностью избавиться от структуры Verbform
и использовать вместо нее std::variant
. Пусть он обрабатывает все эти детали для вас.
using Verbform = std::variant<Irregular, std::string>;