我在联合中删除哪个元素有关系吗

Does it matter which element I delete in a union

我正在写一个翻译器,为此,我想创建一个 class 动词。这个 class 应该只在不规则时保存完整的变位,因为它会产生大列表,占用大量内存。所以这是我的代码:

#include "string.h"  

struct Irregular{
    std::string present;  
    std::string simplepast;  
    std::string pastparticiple;  
}  

union Verbform{  
    Irregular* irregular;  
    std::string* regular;  
    Verbform(Irregular irreg){irregular=new Irregular(irreg);}  
    Verbform(std::string s){regular=new std::string(s);  
    ~Verbbform(){delete regular;}  //here is my problem  
}  

class Verb{  
    public:  
        //some public functions  
    private:  
        Verbform verbform;  
        //some other things;
}  

当我这样做并用一个不规则动词初始化它时,他是删除完整的不规则动词还是只删除第一个字符串?

当我这样做时: ~Verbform(){delete irregular;} 并且我用普通字符串初始化它,他删除的是否比我希望他删除的多?

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;
        }
    }
} 

此外,不要忘记通过添加 copy/move 构造函数和 copy/move 赋值运算符来遵循 Rule of 3/5/0

否则,您应该完全摆脱 Verbform 结构并改用 std::variant。让它为您处理所有这些细节。

using Verbform = std::variant<Irregular, std::string>;