C++, union 与类继承

标签 c++ class inheritance unions

我有一个特定的问题,我被困在哪种方法比另一种更好:

具有枚举的结构,定义 union 成员中的数据 OR 一组具有继承性的类

示例代码如下:

基于 union 的结构

  typedef union TokenValue{
   bool bValue;
   long lvalue;
   double dvalue;
   std::string svalue;
   }

  class Token{
  public:
   TokenType type;
   TokenValue value;
   };

类继承

class TokenBase{
public:
  TokenType type;
  };



class TokenNumber: public TokenBase{
public:
bool isInt;
long lvalue;
double dvalue;
};

class TokenString: public TokenBase{
 public:
  std::string svalue;
 };

最佳答案

这种类型的设计被称为 discriminated union or tagged union .您可以在 Google 上搜索“C++ discriminated union”,以查看此类设计的多个示例和方法。

C union 通常被认为对 C++ 来说有点低级和不安全。作为Pete Becker said ,您基于 union 的解决方案应该提供访问器,而不是直接公开不安全的 union 成员。 union 也有缺点,在 C++11 之前,它们不能包含非 POD 数据结构(因此没有 std::string)。

基于继承的解决方案的优点是您可以开始使用多态性(例如,添加虚拟 PrintTo 方法)。 (当然,您可以通过将 PrintTo 方法添加到基于 union 的解决方案来实现类似的结果,该解决方案在 上执行 switch TokenType,但那不是面向对象的。)

基于 union 的解决方案可能比基于继承的解决方案(无 vtable)更轻量级。对于像词法分析器标记这样低级的东西,这可能更可取。

如果允许使用第三方库,我强烈建议您查看 Boost.Variant获取更多 C++ 方法来区分 union 。

关于C++, union 与类继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12094694/

相关文章:

c++ - 创建4GB std::string时分配错误

c++ - 线程类成员函数;通过初始化列表进行线程初始化

c++ - Cuda(NVCC)编译器的_ITERATOR_DEBUG_LEVEL?

Java:如何将字符串与 toString() 的返回值进行比较

c++ - 当存储新元素时,二维数组会删除元素本身

c# - 从不使用继承的两个类(具有相同的属性名称)获取属性值的优雅解决方案是什么?

class - 为什么我不能 "implements"TypeScript 2.4+ 中的全可选接口(interface)?

c++ - C++ 中的动态绑定(bind)

java - 子类中的 getter 和 setter

c# - 实现一个非常特殊的通用签名