C ++理解Unions和Structs [英] C++ understanding Unions and Structs
问题描述
我来到一个正在进行的项目,其中一些联合会定义如下:
I've come to work on an ongoing project where some unions are defined as follows:
/* header.h */
typedef union my_union_t {
float data[4];
struct {
float varA;
float varB;
float varC;
float varD;
};
} my_union;
如果我理解得很好,工会是为了节省空间,所以sizeof(my_union_t)= MAX在里面。使用上面的语句而不是这个语句的优点是什么:
If I understand well, unions are for saving space, so sizeof(my_union_t) = MAX of the variables in it. What are the advantages of using the statement above instead of this one:
typedef struct my_struct {
float varA;
float varB;
float varC;
float varD;
};
分配给他们的空间不会相同吗?
Won't be the space allocated for both of them the same?
如何初始化来自 my_union 的varA,varB ...?
And how can I initialize varA,varB... from my_union?
推荐答案
联盟不主要用于节省空间,而是实施和类型(为此,你会把 union
放在一些 struct
或 class
也具有将保持运行时标签的区分字段)。此外,我建议您使用最近的C ++标准,至少 C ++ 11
Union are not mostly for saving space, but to implement sum types (for that, you'll put the union
in some struct
or class
having also a discriminating field which would keep the run-time tag). Also, I suggest you to use a recent standard of C++, at least C++11 since it has better support of unions (e.g. permits more easily union of objects and their construction or initialization).
使用联合的优点是能够索引(例如,允许更容易地联合对象及其构造或初始化) n
第0个浮点(0 <= n <= 3)为 u.data [n]
The advantage of using your union is to be able to index the n
-th floating point (with 0 <= n <= 3) as u.data[n]
在一些变量中声明 my_union u;
u.varB = 3.14;
在您的情况下,具有与 u.data [1] = 3.14;
To assign a union field in some variable declared my_union u;
just code e.g. u.varB = 3.14;
which in your case has the same effect as u.data[1] = 3.14;
一个很好的例子是一个很好的例子,一个可变的对象, code> int 或 string
(在这种情况下不能使用派生类):
A good example of well deserved union is a mutable object which can hold either an int
or a string
(you could not use derived classes in that case):
class IntOrString {
bool isint;
union {
int num; // when isint is true
str::string str; // when isint is false
};
public:
IntOrString(int n=0) : isint(true), num(n) {};
IntOrString(std::string s) : isint(false), str(s) {};
IntOrString(const IntOrString& o): isint(o.isint)
{ if (isint) num = o.num; else str = o.str); };
IntOrString(IntOrString&&p) : isint(p.isint)
{ if (isint) num = std::move (p.num);
else str = std::move (p.str); };
~IntOrString() { if (isint) num=0; else str->~std::string(); };
void set (int n)
{ if (!isint) str->~std::string(); isint=true; num=n; };
void set (std::string s) { str = s; isint=false; };
bool is_int() const { return isint; };
int as_int() const { return (isint?num:0; };
const std::string as_string() const { return (isint?"":str;};
};
注意 str
std :: vector< IntOrString> )中安全地使用 IntOrString
Notice the explicit calls of destructor of str
field. Notice also that you can safely use IntOrString
in a standard container (std::vector<IntOrString>
)
另请参见 std :: optional在未来版本的C ++中(其概念上是带有 void
的带标签的联合)
See also std::optional in future versions of C++ (which conceptually is a tagged union with void
)
Ocaml,你只需要代码:
BTW, in Ocaml, you simply code:
type intorstring = Integer of int | String of string;;
,您将使用模式匹配。如果你想做可变的,你需要创建一个记录或其引用。
and you'll use pattern matching. If you wanted to make that mutable, you'll need to make a record or a reference of it.
你最好使用 union
-s以C ++惯用的方式(参见这一般建议)。
You'll better use union
-s in a C++ idiomatic way (see this for general advices).
这篇关于C ++理解Unions和Structs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!