简体   繁体   中英

List of pointers to different types of objects

What would be the best way to implement a list of pointers to different types in C++?

I thought of doing something like this:

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

And then doing the suitable static typecast as soon as I need to access one of the objects in the list.

Another approach would be having different vectors for each object type:

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

The issue is that I need to implement a graph where not all vertices have the same type.

EDIT. Performance is critical. The more efficient the code is the better.

Your best solution would be to have all the classes inherit from the same class and store pointers to the base class in the list. Only use a void* as a last and very,very dangerous solution.

I would rather define a common super-class for all the nodes of your graph, eg

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*列表。

As already mentioned it is better to use base class + its descendants. But if you really want to use C structs for nodes, then you can use a common "C"-style approach - put in the beginning of the each struct some field (let it be int field) to describe a type of the node. It helps you to find out what type each node has:

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 */
  /* ... */
};

There are three options depending on your criteria:

  1. Use a void* pointer: this is explicit in telling any reader of your code "type information is being removed". This covers all cases, but it is entirely up to you to ensure that the type information is retrievable elsewhere it is going to be needed.

  2. Use intrusive-polymorphism, whereby you define a class required for membership in this list, and have to inherit it into any class that wants to be pointed to.

     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. Use non-intrusive polymorphism, whereby you create a derived class from any class that wants membership.

     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 { }; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM