C ++理解Unions和Structs [英] C++ understanding Unions and Structs

查看:267
本文介绍了C ++理解Unions和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屋!

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