-1

This is my program:

#include <iostream>
using namespace std;

class Point
{
private: int x, y;
public:
   Point(int f = 0, int g = 0)
   {
      x = f;
      y = g;
   }
   int getX() const
   {
      return x;
   }
   int getY() const
   {
      return y;
   }
   void setX(const int new_x)
   {
      x = new_x;
   }
   void setY(const int new_y)
   {
      y = new_y;
   }
};
class PointArray
{
private:
   Point * loc;
   int len;
   public:
   PointArray()
   {
      len = 0;
      loc = new Point[0];
   }
   PointArray(const Point * points, const int size)
   {
      len = size;
      loc = new Point[len];
      for(int f = 0; f < len; f++)
         loc[f] = points[f];
   }
   PointArray(const PointArray& pv)
   {
      len = pv.len;
      loc = new Point[len];
      for(int f = 0; f < len; f++)
         loc[f] = pv.loc[f];
   }
   ~PointArray()
   {
      delete[] loc;
   }
   void resize(int n)
   {
      Point *loc1 = new Point[n];
      for(int f = 0; f < len && f < n; f++)
         loc1[f] = loc[f];
      len = n;
      delete[] loc;
      loc = loc1;
   }
   void pushBack(const Point &p)
   {
      resize(len+1);
      loc[len-1] = p;
   }
   void insert(const int pos, const Point &p)
   {
      resize(len+1);
      for(int f = len-1; f > pos; f--)
         loc[f] = loc[f-1];
      loc[pos] = p;
   }
   void remove(const int pos)
   {
      for(int f = pos; f < len-1; f++)
         loc[f] = loc[f+1];
      resize(len-1);
   }
   const int getSize() const
   {
      return len;
   }
   void clear()
   {
      resize(0);
   }
   Point * get(const int pos)
   {
      if (pos >= len)
         return NULL;
      else 
      {
         Point * x = new Point();
         *x = loc[pos];
         return x;
      }
   }
   const Point * get(const int pos) const
   {
      if (pos >= len)
         return NULL;
      else 
      {
         Point * x = new Point();
         *x = loc[pos];
         return x;
      }
   }
};
class Polygon
{
protected: 
   PointArray * loci; 
   int sides;
   static int N;
   public:
   Polygon(Point * loc, int len)
   {
      loci = new PointArray(loc, len);
      sides = len;
      N++;
   }
   Polygon(const PointArray& pv)
   {
      loci = new PointArray(pv);
      sides = pv.getSize();
      N++;
   }
   Polygon(const Polygon& pv)
   {
      loci = new PointArray(*pv.loci);
      sides = pv.sides;
      N++;
   } 
   ~Polygon()
   {
      delete loci;
      N--;
   }
   virtual double area() = 0;
   static int getNumPolygons()
   {
      return N;
   }
   int getNumSides()
   {
      return sides;
   }
   const PointArray * getPoints()
   {
      return loci;
   }
};
class Rectangle : public Polygon
{ 
private:
   typedef Polygon super;
   void makeRectangle(const Point e, const Point r)
   {
      Point * loci = new Point[4];
      loci[0] = e;
      loci[2] = r;
      loci[1] = new Point(e.getX(), r.getY());
      loci[3] = new Point(r.getX(), e.getY());
   }
   void makeRectangle (const int x1, const int x2, const int y1, const int y2)
   {
      Point * loci = new Point[4];
      loci[0] = new Point(x1, y1);
      loci[1] = new Point(x2, y1);
      loci[2] = new Point(x2, y2);
      loci[3] = new Point(x1, y2);
   }
};

The compiler is giving me these errors in the two overloaded makeRectangle() when they call the Point(int, int) constructor, saying:

geometry.cpp: In member function 'void Rectangle::makeRectangle(Point, Point)':
geometry.cpp:170:45: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp:171:45: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp: In member function 'void Rectangle::makeRectangle(int, int, int, int)':
geometry.cpp:176:33: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp:177:33: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp:178:33: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]
geometry.cpp:179:33: error: invalid conversion from 'Point*' to 'int' [-fpermissive]
geometry.cpp:8:4: error: initializing argument 1 of 'Point::Point(int, int)' [-fpermissive]

Because x1, x2, y1, and y2 are integers and therefore should be compatible with the Point(int, int) constructor, I do not understand why it is giving me the error: "invalid conversion from 'Point*' to 'int'".

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
AlekTHyra
  • 1
  • 1
  • 3
    Way too much irrelevant code. Bottom line is that C++ isn't Java and you're doing too much allocating and raw pointer handling, and you're mixing pointers and values. Also, hidden `new[]`/`delete` mismatches aside from the compiler errors. I don't even know where to start pointing out things that are wrong. – Sebastian Redl Mar 17 '14 at 14:51
  • For a start, `loci[0]` is a `Point` not a `Point *`, so you shouldn't `new` into it. – Shahbaz Mar 17 '14 at 14:52
  • And which is line 170? It is important, when asking, to provide a problem statement that is as small and concise as possible, and to indicate both the error message en the location in the code you posted. – David Rodríguez - dribeas Mar 17 '14 at 16:10

1 Answers1

1

Getters and setters

Having getters and setters for the sake of having them is never a good idea. Therefore your code for Point can be reduced to:

struct Point {
    int x;
    int y;
};

Which not only is easier and faster to read, but is just as constant correct as your solution was.


The array

Your PointArray class is less than reusable. You can use standard containers instead. Your PointArray class can be reduced to:

using PointArray = std::vector<Point>;

The Polygon base class

The Polygon class can also be improved. First of all you don't need loci to be dynamically allocated. You should use:

class Polygon {
protected: 
   PointArray loci; 
   int sides;
   static int N;

Now, for the constructor you could use the following instead of the C-style array that you are expecting from the first constructor:

public:
   Polygon(const PointArray& loc) {
      loci = loc
      sides = loc.size();
      N++;
   }

As you can see there's no need for the len argument. You could also use an std::initializer_list to allow expressions like:

Polygon x { Point(...), Point(...), Point(...), ... };

And here's how:

    Polygon(const std::initializer_list<Point> list)
        : loci(list)
        , sides(list.size())
        { N++; }

And after your smart edit you can get rid of the custom copy constructor and destructor, effectively following the Rule of Zero.

The rest is pretty much the same:

    virtual double area() = 0;
    static int getNumPolygons() { return N; }
    int getNumSides() { return sides; }

except for getPoints. I'd suggest two different overloads: const and non-const:

    PointArray& getPoints() { return loci; }
    const PointArray& getPoints() const { return loci; }
};

The Rectangle class

And finally your rectangle class can, of course, be improved:

class Rectangle : public Polygon { 
private:
    void makeRectangle(const Point& e, const Point& r) {
        loci.push_back(e);
        loci.push_back(r);
        loci.emplace_back(e.x, r.y);
        loci.emplace_back(r.x, e.y);
    }

    void makeRectangle (const int x1, const int x2, const int y1, const int y2) {
        loci.emplace_back(x1, y1);
        loci.emplace_back(x2, y1);
        loci.emplace_back(x2, y2);
        loci.emplace_back(x1, y2);
    }
};

Conclusion

After this simple refactoring, all your errors should be gone and your code should be much shorter and readable.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Shoe
  • 74,840
  • 36
  • 166
  • 272