【问题标题】:C/C++ trick: define a unified type for multiple different types?C/C++ 技巧:为多种不同类型定义统一类型?
【发布时间】:2014-12-26 22:24:48
【问题描述】:

我正在研究一些编译器,我有多种不同的类型:

Box*
BoxedInt*
BoxedString*
...

它们基本上都是指向不同对象的指针,我想创建一个统一的类型,称为ObjectPointer,可以表示所有这些指针类型。我倾向于使用void *,因为我不想到处都有演员。我能做些什么?我可以这样做吗:

typedef Box*      ObjectPointer
typedef BoxedInt* ObjectPointer
....

或者还有其他方法可以做到吗?对于这些指针,我只想要一个algebraic data type 之类的东西。顺便说一句,我使用的是clang

我打算像普通类型一样使用新类型ObjectPointer。它不应该是类、结构或联合。假设我在更改后有一个函数Box* add(BoxedInt* lhs, BoxedInt rhs),它应该只是ObjectPointer add(ObjectPointer lhs, ObjectPointer rhs)

【问题讨论】:

  • 不允许将这些类的定义更改为继承自ObjectPointer吗?
  • 取决于您打算如何使用这种组合类型。请添加更多详细信息。
  • 那么,您使用的是哪种语言?还请删除标题中的标签,它们不属于那里。

标签: c++ c types compilation clang


【解决方案1】:

C 中,您可以使用union 类型,它包含上述所有元素的指针:

union UnifiedType {
  Box* boxPtr;
  BoxedInt* boxedIntPrt;
  BoxedString* boxedStringPtr;
};

查看here 了解更多信息。

不过,在C++ 中,您可以为所有描述的类型使用一个(如果需要的话是抽象的)超类,并将它们设置为它的扩展。然后,您可以根据需要使用基类指针。更多信息请关注here

class BoxedBase { /*....*/ }

class Box : public BoxedBase { /*....*/ }
class BoxedInt : public BoxedBase { /*....*/ }
class BoxedString : public BoxedBase { /*....*/ }

然后您可以像这样typedef 指针:

typedef BoxedBase* ObjectPointer

【讨论】:

  • public classpublic abstract class 不是 C++。
【解决方案2】:

你不能定义“这个东西可以容纳任意数量的不相关类型”。但是,如果您关联类型(使用基类),则可以使用多态性。

class Object { ... }
class Box : public Object { ... }
class BoxedInt : public Object { ... }
...
typedef Object * ObjectPointer;

【讨论】:

    【解决方案3】:

    从问题描述中,听起来您想使用模板。比如你写一个函数

    template <typename T>
    void ExampleFunction(T* object)
    {
         //do boxy stuff
    }
    

    你可以用你感兴趣的所有类型来调用它,只要一个统一的函数定义是有意义的。你可以说ExampleFunction(ptr),其中ptr 有任何类型,当替换ExampleFunction 中的T 时会有意义。

    【讨论】:

      【解决方案4】:

      您可以按照您的建议进行操作(即使用 void *)来指向所有对象,但我只会在您用尽所有其他可能性后使用此选项,因为您将不得不 void * 施放它并失去所有编译器大小/类型检查(实际上是重新解释转换)。

      编辑: 例如当您从没有类型信息(如处理器间消息等)的外部源接收“已知”数据时,您可能需要使用它。

      您最好的选择是将您的各种盒子类作为基类,并让其他类继承它们。这通常是 c++ 中的最佳方式,因为您的基类指针可以指向任何派生类。您仍然需要强制转换才能访问最终类型(例如 BoxedInt),但您可以使用更安全的动态强制转换;通常,您可以使用某种查找功能来执行此操作,或者使用工厂模式...

      【讨论】:

        【解决方案5】:

        解决这个问题的标准方法是多态。所以,正如其他人所指出的,在 C++ 中你会写

        class Object { ... };
        class Box : public Object { ... };
        class BoxedInt : public Box { ... };
        class BoxedString : public Box { ... };
        ...
        

        在 C 中,您可以做完全相同的事情,即使它不会避免强制转换指针:

        typedef struct Object { ... } Object;
        typedef struct Box { Object super; ... } Box;
        typedef struct BoxedInt { Box super; ... } BoxedInt;
        typedef struct BoxedString { Box super; ... } BoxedString;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-15
          • 1970-01-01
          • 2012-12-23
          • 2020-12-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多