C++容器基本问题

C++容器基本问题,c++,storage,containers,C++,Storage,Containers,以下情况应如何处理: 我有一些几何存储,这是顶点类型的模板 这很好,除非我想在一个容器中存储不同类型的几何体,例如几何体g1和几何体g2 struct GeometryBase { // Non-template methods might go here. // Don't forget to declare the base class destructor virtual. }; template <typename T> struct Geometry :

以下情况应如何处理:

我有一些几何存储,这是顶点类型的模板

这很好,除非我想在一个容器中存储不同类型的几何体,例如几何体g1和几何体g2

struct GeometryBase
{
    // Non-template methods might go here.
    // Don't forget to declare the base class destructor virtual.
};

template <typename T> struct Geometry : public GeometryBase
{
    // Template methods go here
};
这可能吗

或者我应该如何实现几何体存储,使用一个容器存储和检索不同类型的几何体,或者以某种方式将T类型映射到几何体类型

有什么建议吗


谢谢。

由于容器绑定到它可以包含的一种类型的数据,您可以创建一个类GeometryBase,从中派生所有几何图形,然后将GeometryBase指针存储在容器中

struct GeometryBase
{
    // Non-template methods might go here.
    // Don't forget to declare the base class destructor virtual.
};

template <typename T> struct Geometry : public GeometryBase
{
    // Template methods go here
};
编辑: 在某个时刻,您必须决定要使用哪种类型的顶点容器来获得我的方法,或者要使用vertex Vijay Mathew的方法执行什么操作,然后您必须进行动态_cast以获得对派生类方法的访问

另一项建议: 如果这些类型与您在评论中描述的不同,那么实际上最好将它们视为不同的类型。 例如,可以为每个几何图形样板实例创建单独的容器

class SomeStorageClass
{
/* ... */
private:
    std::vector< Geometry<Vertex1> > m_vertex1Geometries;
    std::vector< Geometry<Vertex2> > m_vertex2Geometries;
};

如果您的函数使用Vertex1::GetPos在一种几何体上运行,以您的示例或其他Vertex2::GetUV为例,那么这些函数的实现方式可能非常不同,因此应该是需要不同类型参数的独立函数。

异构容器,即。,存储不止一种类型的对象会带来很多问题——举个明显的例子,当你检索一个对象时,你必须做一些事情来找出你要检索的是哪种类型的对象

内置C++的容器采用简单的路径:它们是同构的,它们只存储一种类型的对象。如果您想存储两种不同类型的对象,那么您需要将这两种对象包装成第三种类型,并将其存储在容器中,通常还需要一些东西来指示特定对象的实际类型。例如,您可以这样做:

class vertex1 {};

class vertex2 {};

class vertex {
    vertex1 *v1;
    vertex2 *v2;
public:
    vertex(vertex1 *init1) : v1(init1), v2(NULL) {}
    vertex(vertex2 *init2) : v1(NULL), v2(init2) {}
};

std::vector<vertex> vertices;
当然,有很多变体,例如,存储指向基类的指针,但最终归结为一件事:集合本身持有一种类型的对象,而该类型以某种方式或其他方式管理您需要处理的其他两种类型。

因为GetVertex只返回Vertex类型的对象,我建议您从泛型转向面向对象的设计

class Vertex
{
   ....
};

class Vertex1 : public Vertex 
{
   ....
};

class Vertex2 : public Vertex 
{
   ....
};

typedef std::vector<Vertex*> Vertices;

struct Geometry
{
    const Vertices& GetVertices() const { .... }
    ....
};

记住放置一个虚拟析构函数:如果我选择你的方式,我应该如何实现那些像GetVertices一样的访问器?比如-我不能再返回std::vector&并且为每个GeometryBase调用dynamic_cast是无意义的…顶点的类型应该是std::vector或std::vector对吗?@Vijay:不,在这种情况下不是。我们不是创建指针容器,而是创建一个对象容器,这些对象本身包含两个指针。我有理由认为某些引用容器是不允许的。如果我想让Vertex1包含像GetPos和GetNormal这样的成员,而Vertex2也引入GetUV方法,则您的示例将失败,因为它不能添加到基本超类中。@HardCoder1986:它仍然有效,您只需在运行时向下转换为适当的类型。@HardCoder1986 dynamic_cast。此外,这个问题并不是最初问题的一部分。我的答案显示了普通的C++习语,用来处理像所描述的情况。除了向下投射不是很酷的事实:@HardCoder1986:可能不酷,但如果您想从同构容器中获取不同类型的对象,这是必要的。顺便问一下,GetVertices如何从常量函数返回非常量引用?我觉得这有点不靠谱。这里的用例是什么?
class IGeometry
{
public:
    virtual const void* RawVertices() const = 0;
    virtual ~IGeometry() {}

    template <typename T>
    std::vector<T>& GetVertices() const 
    { 
        typedef const Geometry<T>* AppropriateDerivedClass;
        return dynamic_cast<AppropriateDerivedClass>(this)->GetVertices();
    };
};