我试图使用具有一些非原始变量的联合(C ++),但是我试图为该类创建析构函数。正如我所读到的那样,无法猜测正在使用联合的哪个变量,因此没有隐式析构函数,并且因为我在堆栈上使用此联合,所以编译器错误会删除析构函数。工会如下:
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;
}
};
但由于我不是工会大师,我不知道这是否会导致其他问题,例如分配的内存永远不会被解除分配,或类似的东西。这种交换策略能否在没有缺陷和问题的情况下使用?
答案 0 :(得分: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;
};
答案 1 :(得分:3)
如果要在C ++ 11中的联合中使用 aP.controller('skillsCtrl', ['$scope', function ($scope) {
$scope.oneSkills = ["HTML", "CSS", "Sass", "Javascript", "Jquery", "AngularJS"];
$scope.twoSkills = ["Grunt", "Node", "Ruby on Rails","Adobe Photoshop", "Adobe Illustrator"]; }]);
,则必须显式调用其析构函数,并使用new来构造它。 cppreference.com的示例:
std::string