Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++, data model, templates

Tags:

c++

datamodel

I am using a data model with classes: 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;
...
};

To manage instances of these classes the folowing classes allowing loading points from file, adding/removing points, clearing list, printing are used...

List of 2D points

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);
...
}

List of 3D points

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);
 ...
}

Source code of PointGeo class is similar...

So differences in the code between the classes are small. They differ in methods for loading, printing, saving data.

Would it be inappropriate to design a class replacing all three classes? How to create methods for loading, printing data specific for the data type?

The similar situation occurs for the dynamic alocation: Node2D, Node3D,... classes. Class Node2D stores some topological relationships and using pointers to other nodes or faces... In such case all three classes will have a different destructor...

List of 2D points

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

Thank you very much for your comments and suggestions. I am writing geometric library and thinking about the most suitable data model.

like image 444
Ian Avatar asked Mar 14 '26 10:03

Ian


1 Answers

You could put the I/O operations directly to Point2D Point3D types. Then the you wouldn't have to create additional list class since printing/reading would be as simple as:

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

If this isn't viable, at least the same list class could be used as template to serve both Point3D and Point2D


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!