如何为类似union的类编写析构函数

ran*_*alt 7 c++ destructor memory-management unions c++11

我正在尝试使用具有一些非原始变量的union(C++),但是我一直试图为该类创建析构函数.正如我所读到的那样,无法猜测正在使用的union的哪个变量因此没有隐式析构函数,并且因为我在堆栈上使用了这个union,所以编译器错误会删除析构函数.工会如下:

struct LuaVariant {
    LuaVariant() : type(VARIANT_NONE) { }

    LuaVariantType_t type;
    union {
        std::string text;
        Position pos;
        uint32_t number;
    };
};
Run Code Online (Sandbox Code Playgroud)

type变量保存正在使用的union的哪个字段(从枚举中选择),以便从union中读取,并且它可以用于猜测应该删除哪个值.我尝试了一些不同的方法,但没有一个工作.首先,只是尝试了默认的析构函数:

~LuaVariant() = default;
Run Code Online (Sandbox Code Playgroud)

它不起作用,因为默认值是......已删除.所以,我尝试用空值交换值,这样内容就会被删除,并且没有"泄漏"空值的问题:

~LuaVariant() {
    switch (type) {
        case VARIANT_POSITION:
        case VARIANT_TARGETPOSITION: {
            Position p;
            std::swap(p, pos);
            break;
        }
        case VARIANT_STRING: {
            std::string s;
            std::swap(s, text);
            break;
        }
        default:
            number = 0;
            break;
    }
};
Run Code Online (Sandbox Code Playgroud)

但由于我不是工会的主人,我不知道这是否会导致其他问题,例如分配的内存永远不会被解除分配,或类似的东西.这种交换策略能否在没有缺陷和问题的情况下使用?

utn*_*tim 9

这种分组(用于区分类型的union + enum值)称为区分联合.

你可以调用任何构造/破坏,因为联合本身不能(如果可以的话,它也能够区分联合中的初始化/非初始化类型,并且你不需要枚举).

码:

class LuaVariant // no public access to the raw union
{
public:
    LuaVariant() : type(VARIANT_NONE) { }
    ~LuaVariant() { destroy_value(); }

    void text(std::string value) // here's a setter example
    {
        using std::string;
        destroy_value();
        type = VARIANT_TEXT;
        new (&value.text) string{ std::move(value) };
    }
private:

    void destroy_value()
    {
        using std::string;
        switch(type)
        {
        case VARIANT_TEXT:
            (&value.text)->string::~string(); 
            break;
        case VARIANT_POSITION:
            (&value.pos)->Position::~Position(); 
            break;
        case VARIANT_NUMBER:
            value.number = 0;
            break;
        default:
            break;
        }
    }

    LuaVariantType_t type;
    union {
        std::string text;
        Position pos;
        uint32_t number;
    } value;
};
Run Code Online (Sandbox Code Playgroud)

  • 我需要在我的工会中添加一个空的析构函数才能使它工作.我错过了什么吗?我有一个"值::〜value()是一个删除的函数"否则 (2认同)