我正在尝试使用具有一些非原始变量的 union (C++),但我一直在尝试为该类创建析构函数。正如我所读到的,不可能猜测正在使用 union 的哪个变量,因此没有隐式析构函数,并且当我在堆栈上使用这个 union 时,编译器会错误地指出析构函数已被删除。 union 体如下:
struct LuaVariant {
LuaVariant() : type(VARIANT_NONE) { }
LuaVariantType_t type;
union {
std::string text;
Position pos;
uint32_t number;
};
};
type
变量保存正在使用 union 体的哪个字段(从枚举中选择),目的是从 union 体中读取,它可以用来猜测应该删除什么值。我尝试了一些不同的方法,但都没有奏效。首先,只是尝试了默认的析构函数:
~LuaVariant() = default;
它没有用,因为默认是...删除。所以,我尝试用一个空值交换该值,这样内容就会被删除,并且“泄漏”一个空值也不会有问题:
~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;
}
};
但由于我不是 union 的高手,我不知道这是否会导致其他问题,例如分配的内存永远不会被释放,或类似的问题。这种交换策略可以毫无缺陷和问题地使用吗?
最佳答案
这种分组( union + 区分类型的枚举值)称为可区分 union 。
调用任何构造/析构取决于您,因为 union 本身不能(如果可以,它也能够区分 union 内的已初始化/未初始化类型,并且您不需要枚举)。
代码:
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;
};
关于c++ - 如何为类 union 类编写析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31690652/