MatG
MatG

Reputation: 795

Advice on c++ class interface design: how would you name these two methods to make them obvious?

I have a very simple concrete class that represents a point in 2D space, it has two methods to shift the point given a radius and an angle: one modifies the object itself, the other creates another object leaving the first one unchanged:

template<class T =double> class cls_2DPoint
{
    ...
    cls_2DPoint<T>& polar_move(const T r, const double a) noexcept
       {
        x+=r*std::cos(a); y+=r*std::sin(a); return *this;
       }
    cls_2DPoint<T> polar_moved(const T r, const double a) const noexcept
       {
        return cls_2DPoint<T>(x+r*std::cos(a), y+r*std::sin(a));
       }
    ...
    T x,y;
};

This is actually code that I'm using! While reviewing it I realized that this was a reckless design: not obvious, error prone, making the user code less readable. Since I'm struggling to find a convincing alternative, I thought to ask advice here: are there general conventions/guidelines for naming modifying and non-modifying methods? Are there best practices that could help me here to improve the design?

Upvotes: 0

Views: 64

Answers (2)

Muratcan Akcay
Muratcan Akcay

Reputation: 155

I would name them like this:

template<class T =double> class cls_2DPoint
{
    ...

    cls_2DPoint<T>& polarMovePoint(const T r, const double a) noexcept
       {
        x+=r*std::cos(a); y+=r*std::sin(a); return *this;
       }

    cls_2DPoint<T> polarMovePointClone(const T r, const double a) const noexcept
       {
        return cls_2DPoint<T>(x+r*std::cos(a), y+r*std::sin(a));
       }
    ...
    T x,y;
};

This type of labeling would let me know which function moves the point itself and which function creates a clone of the point and than moves that.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206607

My suggestions.

Use namespace instead of prefix for class name

namespace cls2D
{
   class Point { ... };
}

Add class Vector

namespace cls2D
{
   class Point { ... };
   class Vector { ... };
}

Define operator methods

Define operator methods that work with the two object types. Prefer non-member functions if you can get away with it.

namespace cls2D
{
   class Vector;

   class Point
   { 
      public:

         Point& operator+=(Vector v);
         Point& operator-=(Vector v);

      private:
         double x = 0;
         double y = 0;
      
   };

   class Vector
   {
      public:

         Vector& operator+=(Vector v);
         Vector& operator-=(Vector v);

      private:
         double x = 0;
         double y = 0;
   };

   Point from_polar(double r, double th);
   Point from_vector(Vector v);
   Vector from_point(Point p);

   Point operator+(Point p, Vector v);
   Point operator+(Vector v, Point p);
   Vector operator+(Vector v1, Vector v2);

   Vector operator-(Point p1, Point p2);
   Vector operator-(Vector v1, Vector v2);

}

Please note that Point and Vector have the same member data. Hence, it's tempting to use just one class to represent both. However, I think of them as two different abstractions and deserve to be different classes.

I removed the template part in my answer to make illustration of the idea simpler.

I assume you know how to add the necessary costructors to the classes.

Upvotes: 1

Related Questions