我正在使用带有类的数据模型: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;
...
};
要管理这些类的实例,可以使用允许从文件加载点,添加/删除点,清除列表,打印的下列类...
2D点列表
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存储一些拓扑关系并使用指向其他节点或面的指针......在这种情况下,所有三个类都将具有不同的析构函数......
2D点列表
template <class T>
struct TNodes2DList
{
typedef std::vector <Node2D <T> *> Type;
};
非常感谢您的意见和建议。我正在编写几何库并思考最合适的数据模型。
答案 0 :(得分:4)
您可以将I / O操作直接置于Point2D
Point3D
类型。然后你就不必创建额外的列表类,因为打印/阅读就像这样简单:
for (std::vector<Point3D>::iterator i = a.begin; i != a.end(); ++i) {
i->print_to_file(file);
}
如果这不可行,至少可以使用相同的列表类作为模板来同时为Point3D和Point2D提供
答案 1 :(得分:1)
根据您对课程的处理方式,您可以执行以下操作:
template<class T, unsigned int count = 2>
class Point
{
public:
T t[count];
// other data members here
};
然而,如果你正在做类似矢量数学的事情(例如交叉产品,点积,规范化等),这样做会使类比具有2个类(2D和3D)复杂得多。除非你在Geo类中做一些专门的工作,否则根本不需要有不同的2D和Geo形式。