union使用

2020-09-29  本文已影响0人  zlcook
union Token {
 char cval;
 int ival;
};
Token def ; // 未初始化
Token tk = {'a'} ; // 初始值显示初始化,用于第一个cval成员
 tk.ival = 5;  // 此时cval是未定义状态

包含类类型的union

templace<class T>
class StatusOr {
public:
StatusOr() : state_(kVoid) {}

StatusOr(const StatusOr& rhs) : state_(rhs.state_) {
       if (state_ == kValue) {
            new (&variant_) Variant(rhs.variant_.value_);
        } else if (state_ == kStatus) {
            new (&variant_) Variant(rhs.variant_.status_);
        }
}


StatusOr(Status st) : variant_(st), state_(kStatus) {}

StatusOr(T&&  v) : variant_(v), state_(kValue) {}

~StatusOr() {
  if (state_ == kStatus) {
    variant_.status_.~Status();
  } else (state_ == kValue) {
    variant_.value_.~T();
  }
  state_ = kVoid;
}

private:
// Variant状态判别式
enum State {
   kValue = 0,
   kStatus = 1,
   kVoid = 2,
}; 

union Variant {
  Variant() {}
  Variant(Status status) : status_(status) {}
  Variant(T val) : value_(val) {}
// 如果不自己定义析构,那么Variant的析构默认是删除的,那么StatusOr的析构默认也是删除的
  ~Variant() {}  // 类类型成员的析构交给StatusOr类管理
  Status status_;  // 定义类构造函数和拷贝控制成员的类类型成员
  T      value_;
 }; 

  Variant variant_;  // 未定义
   State state_;
};
Token tk = {'a'} ; // 初始值显示初始化,用于第一个cval成员
 tk.ival = 5;  // 此时cval是未定义状态
tk.cval = 'b';   // 普通的赋值语句就可以改变union保存的值。
// 拷贝构造,union之前没有值,直接进行构造
StatusOr(const StatusOr& rhs) : state_(rhs.state_) {
       if (state_ == kValue) {
            new (&variant_) Variant(rhs.variant_.value_);
        } else if (state_ == kStatus) {
            new (&variant_) Variant(rhs.variant_.status_);
        }
}

// 拷贝赋值,union之前可能有值,涉及到更改,所以会有析构,再次构造
StatusOr& operator=(const StatusOr& rhs) {
  if (this == &rhs) {
    return *this;
  }
  // 先析构
   if (state_ == kValue) {
        variant_.value_.~T();
   } else if (state_ == kStatus) {
        variant_.status_.~Status();
   }
   // 在构造赋值
   if (rhs.state_ == kValue) {
        new (&variant_) Variant(rhs.value_);
         state_ = kValue;
   } else if (rhs.state_ == kStatus) {
        new (&variant_) Variant(rhs.status_);
         state_ = kStatus;
   }
   return *this;
}
上一篇 下一篇

猜你喜欢

热点阅读