指向不同类型对象的指针列表

List of pointers to different types of objects

本文关键字:指针 列表 对象 同类型      更新时间:2023-10-16

C++中实现指向不同类型的指针列表的最佳方法是什么?

我想做这样的事情:

enum MyType {...};
typedef std::pair<MyType, void*> Ptr;
std::vector <Ptr> list;

然后在我需要访问列表中的一个对象时立即执行合适的静态类型转换。

另一种方法是为每个对象类型使用不同的向量:

std::vector<ClassA*> list_a;
std::vector<ClassB*> list_b;
...

问题是我需要实现一个图,其中并非所有顶点都具有相同的类型。

编辑。性能至关重要。代码越高效越好。

最好的解决方案是让所有类都继承自同一个类,并在列表中存储指向基类的指针。仅使用void*作为最后且非常非常危险的解决方案。

我宁愿为图的所有节点定义一个通用的超类,例如

class Node {
   // probably some fields giving siblings, or at least a unique number
};
class GreenNode : public Node {
    // etc...
};
class YellowNode : public Node {
};
class BlackLeaf : public Node {
};

从基类Vertex继承所有不同类型的顶点,然后使用Vertex*列表。

如前所述,最好使用基类 + 其后代。但是如果你真的想对节点使用 C 结构,那么你可以使用一个常见的"C"式方法 - 在每个结构的开头放一些字段(让它成为 int 字段)来描述节点的一种类型。它可以帮助您找出每个节点的类型:

typedef enum {
  SMALL_NODE = 1,
  NORML_NODE,
  HUUGE_NODE,
} type;
struct small_node {
  unsigned int type; /* type above - SMALL_NODE */
  /* ... */
};
struct norml_node {
  unsigned int type; /* type above - NORML_NODE */
  /* ... */
};
struct huuge_node {
  unsigned int type; /* type above - HUUGE_NODE */
  /* ... */
};

根据您的条件,有三个选项:

  1. 使用 void* 指针:这在告诉任何代码的读者"正在删除类型信息"时是明确的。这涵盖了所有情况,但完全取决于您确保类型信息可以在需要的其他地方检索。

  2. 使用侵入式多态性,即定义此列表中成员资格所需的类,并且必须将其继承到要指向的任何类中。

    struct ListInterface { // struct for defaulting to public
        void Poke(uint addr, uint value) = 0;
        uint Poke(uint addr) const = 0;
    };
    class SplineVertex : public Vertex, public ListInterface {
        ...
    };
    
  3. 使用非侵入式多态性,从而从需要成员资格的任何类创建派生类。

    struct ListInterface { // struct for defaulting to public
        void Poke(uint addr, uint value) = 0;
        uint Poke(uint addr) const = 0;
    };
    class SplineVertex : public Vertex {
        ...
    };
    class SplineVertexHolder : public SplineVertex, public ListInterface {
    };