当我给出的参数是一个int时,为什么这是一个无效的转换

时间:2014-03-17 14:47:42

标签: c++

这是我的计划:

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

编译器在调用Point(int,int)构造函数时,在两个重载的makeRectangle()中给出了这些错误,并说:

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]

因为x1,x2,y1和y2是整数,因此应该与Point(int,int)构造函数兼容,我不明白它为什么会给我错误:“从'Point *'无效转换为“诠释””。

1 个答案:

答案 0 :(得分:1)

  

吸气者和二传手

为了拥有它们而拥有getter和setter是never a good idea。因此,Point的代码可以简化为:

struct Point {
    int x;
    int y;
};

这不仅更简单,更快速,而且与您的解决方案一样正确。


  

数组

您的PointArray课程不足以重复使用。您可以使用标准容器。您的PointArray课程可以简化为:

using PointArray = std::vector<Point>;

  

Polygon基类

Polygon课程也可以改进。首先,您不需要动态分配loci。你应该使用:

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

现在,对于构造函数,您可以使用以下代替第一个构造函数所期望的C样式数组:

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

正如您所看到的那样,len参数不需要。您还可以使用std::initializer_list来允许表达式:

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

以下是:

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

在智能编辑之后,您可以有效地遵循Rule of Zero来摆脱自定义复制构造函数和析构函数。

其余几乎相同:

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

除了getPoints。我建议两种不同的重载:const和非const

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

  

Rectangle类

最后,您的矩形类当然可以改进:

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

  

结论

在这个简单的重构之后,你的所有错误都应该消失,你的代码应该更短更易读。