Я использую модель данных с классами: 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;
};
Большое спасибо за ваши комментарии и предложения. Я пишу геометрическую библиотеку и думаю о наиболее подходящей модели данных.