gpt4 book ai didi

类 union 类的 C++11 移动构造函数

转载 作者:可可西里 更新时间:2023-11-01 18:38:28 24 4
gpt4 key购买 nike

有没有更好的方法来为类 union 类构建移动构造函数?如果我有一个类似 union 的类,如以下代码中的类,有没有一种方法可以构建不需要 switch 语句的类或移动构造函数,如以下代码中的移动构造函数。

class S {
private:
enum {CHAR, INT, DOUBLE} type; // tag
// anonymous union
union {
char c;
int n;
double d;
};

public:
// constructor if the union were to hold a character
AS(const char c) {
this->tag = AS::CHAR;
this->c = c;
}
// constructor if the union were to hold a int
AS(const int i) {
this->tag = AS::INT;
this->n = i;
}
// constructor if the union were to hold a double
AS(const double d) {
this->tag = AS::DOUBLE;
this->d = d;
}

// Move constructor with switch statement
S(S &&src) : type(std::move(src.type)) {
switch(type) {
case CHAR:
this->c = src.c);
src.c = 0;
break;
case INT:
this->n = src.n;
src.n = 0;
break;
case DOUBLE:
this->d = src.d;
src.d = 0
break;
default:
break;
}
}
};

最佳答案

不,没有更好的方法。如果你想安全地从包含任意类型的 union 中移动,你必须从最后写入的 union 字段(如果有的话)中这样做。另一个相反的答案是错误的,考虑一个例子

union SomethingLikeThisIsGoingToHappenInPractice {
std::string what_we_actually_want_to_move;
char what_we_do_not_care_about[sizeof(std::string)+1];
};

如果您在此处使用“最大”类型的移动构造函数,则必须在此处选择 char 数组,尽管移动实际上并没有真正做任何事情。如果设置了 std::string 字段,您希望移动其内部缓冲区,如果您查看 char 数组,则不会发生这种情况。还要记住,移动语义是关于语义的,而不是关于移动内存的。如果这是问题所在,您可以始终使用 memmove 并完成它,不需要 C++11。

这甚至没有涉及从您尚未编写的 union 成员中读取成为 C++ 中的 UB 的问题,即使对于基本类型,但尤其是对于类类型。

TL;DR 如果您发现自己处于这种情况,请使用 OP 最初提出的解决方案,而不是接受的答案中的内容。


PS:当然,如果你只是移动一个只包含普通可移动事物的 union ,比如原始类型,你可以只使用 union 的默认移动构造函数,它只会复制内存;在那种情况下,除了为了一致性之外,一开始就有一个移动构造函数真的不值得。

关于类 union 类的 C++11 移动构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29000164/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com