如何编写类似union的类的析构函数 [英] How to write destructor for union-like class

查看:220
本文介绍了如何编写类似union的类的析构函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用一个具有一些非原始变量的联合(C ++),但我坚持试图创建该类的析构函数。正如我已经阅读,不可能猜测联合的什么变量正在被使用,所以没有隐式析构函数,并且由于我在堆栈上使用这个联合,析构函数的编译器错误被删除。联合如下:

I'm trying to use an union (C++) that has some non-primitive variables, but I'm stuck trying to create the destructor for that class. As I have read, it is not possible to guess what variable of the union is being used so there is no implicit destructor, and as I'm using this union on the stack, the compiler errors that the destructor is deleted. The union is as follows:

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

    LuaVariantType_t type;
    union {
        std::string text;
        Position pos;
        uint32_t number;
    };
};

类型使用联合(从枚举中选择),用于从联合读取的目的,并且它可以用于猜测应该删除什么值。我尝试了一些不同的方法,但没有一个工作。首先,只是尝试默认析构函数:

The type variable holds what field of the union is being used (chosen from an enum), for the purpose of reading from the union and it could be used to guess what value should be deleted. I tried some different approaches but none of them worked. First of all, just tried the default destructor:

~LuaVariant() = default;

它没有工作,因为默认是...删除。所以,我试着用空值交换值,以便内容将被删除,并且没有问题泄漏一个空值:

It did not work, as the default is... deleted. So, I tried swapping the value with an empty one, so that the contents would be erased and there would be no problem "leaking" an empty value:

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

但是由于我不是工会的主人,我不知道是否会导致其他问题,例如分配的内存从未被释放,或类似的东西。

But as I am not a master of the unions, I don't know if that can cause other problems, such as allocated memory that never gets deallocated, or something like that. Can this swap strategy be used without flaws and issues?

推荐答案

这个分组(union + enum value for discriminating type)被称为

This grouping (union + enum value for discriminating type) is called a discriminated union.

这将取决于你调用任何构造/销毁,因为联合本身不能(如果可能,它也能够区分初始化/

It will be up to you to call any construction/destruction, because the union itself cannot (if it could, it would also be able to discriminate for initialized/non-initialized types within the union, and you would not need the 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;
};

这篇关于如何编写类似union的类的析构函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆