3

我正在使用带有类的数据模型:Point2D、Point3D、PointGeo:

template <class T>
class Point2D
{
    protected:
            T x;
            T y;
...
};


template <class T>
class Point3D
{
    protected:
            T x;
            T y;
            T z;
...
};

template <class T>
class PointGeo
{
    protected:
            T lat;
            T lon;
...
};

为了管理这些类的实例,使用以下类允许从文件加载点、添加/删除点、清除列表、打印......

二维点列表

template <class T>
struct TPoints2DList
{
    typedef std::vector <Point2D <T> > Type;
};


template <class T>
class Points2DList
{
    private:
            typename TPoints2DList <T>::Type  points;


    public:
            Points2DList() : points ( 0 ) {}
            virtual ~Points2DList() {points.clear();}
            Points2DList ( const Points2DList &source );
            typename TPoints2DList <T>::Type ::iterator begin() { return points.begin(); }
            typename TPoints2DList <T>::Type::const_iterator begin() const { return points.begin(); }
            typename TPoints2DList <T>::Type::iterator end() { return points.end(); }
            typename TPoints2DList <T>::Type::const_iterator end() const { return points.end(); }
            Point2D <T> &operator [] ( int index ) {return points[index];}
            const Point2D <T> &operator [] ( int index ) const {return points[index];}

    public:
            //Overloaded member functions
            inline void clear() {points.clear();};
            inline void pop_back() {points.pop_back();}
            inline void push_back ( Point2D <T> p ) { points.push_back ( p );}
            inline unsigned int size() const {return points.size();}

    public:
            //Other methods
            void loadPointsFromFile ( const char *file);
...
}

3D点列表

template <class T>
struct TPoints3DList
{
    typedef std::vector <Point3D <T> > Type;
};


template <class T>
class Points3DList
{
    private:
            typename TPoints3DList <T>::Type  points;


    public:
            Points3DList() : points ( 0 ) {}
            virtual ~Points2DList() {points.clear();}
            Points3DList ( const Points3DList &source );
            typename TPoints3DList <T>::Type ::iterator begin() { return points.begin(); }
            typename TPoints3DList <T>::Type::const_iterator begin() const { return points.begin(); }
            typename TPoints3DList <T>::Type::iterator end() { return points.end(); }
            typename TPoints3DList <T>::Type::const_iterator end() const { return points.end(); }
            Point3D <T> &operator [] ( int index ) {return points[index];}
            const Point3D <T> &operator [] ( int index ) const {return points[index];}

    public:
            inline void clear() {points.clear();};
            inline void pop_back() {points.pop_back();}
            inline void push_back ( Point3D <T> p ) { points.push_back ( p );}
            inline unsigned int size() const {return points.size();}

    public:
            //Other methods
            void loadPointsFromFile ( const char *file);
 ...
}

PointGeo 类的源代码类似...

所以类之间的代码差异很小。它们在加载、打印和保存数据的方法上有所不同。

设计一个替换所有三个类的类是否不合适?如何创建加载、打印特定于数据类型的数据的方法?

动态分配也会出现类似的情况:Node2D、Node3D、... 类。类 Node2D 存储一些拓扑关系并使用指向其他节点或面的指针......在这种情况下,所有三个类都将具有不同的析构函数......

二维点列表

template <class T>
struct TNodes2DList
{
    typedef std::vector <Node2D <T> *> Type;
};

非常感谢您的意见和建议。我正在编写几何库并考虑最合适的数据模型。

4

2 回答 2

4

您可以将 I/O 操作直接放入Point2D Point3D类型。然后,您不必创建额外的列表类,因为打印/阅读将非常简单:

for (std::vector<Point3D>::iterator i = a.begin; i != a.end(); ++i) {
    i->print_to_file(file);
}

如果这不可行,至少可以使用相同的列表类作为模板来服务 Point3D 和 Point2D

于 2010-12-21T19:10:49.873 回答
1

根据您对课程所做的工作,您可以执行以下操作:

template<class T, unsigned int count = 2>
class Point
{
public:
    T t[count];
    // other data members here
};

但是,如果您正在做向量数学之类的事情(例如叉积、点积、归一化等),这样做会使该类比拥有 2 个类(2D 和 3D)复杂得多。除非您在 Geo 类中做一些专门的事情,否则真的没有任何必要拥有不同的 2D 和 Geo 形式。

于 2010-12-21T18:58:18.757 回答