子类构造函数

时间:2013-08-03 15:34:41

标签: c++ inheritance

我在使用C ++中的子类时遇到问题。我有一个Polygon的类和一个Triangle的子类。我希望能够通过传递一个Point *(这是一个自定义类)的矢量和一个Triangle传递三个Point *来声明一个Polygon。

我的理解是Triangle类构造函数应该调用Polygon类的构造函数。

这是我到目前为止所做的:

class Polygon
{
public:
    vector<Point*> pts;
    Polygon(vector<Point*> aPts) : pts(aPts) {};
};
class Triangle : public Polygon
{
public:
    Triangle(Point* A, Point* B, Point* C) 
    {
        vector<Point*> APts;
        APts.push_back(A); APts.push_back(B); APts.push_back(C);
        Polygon(APts);
    }
};

但是,在Triangle构造函数的左括号中我收到错误:

error: no matching function call to 'Polygon::Polygon()'

有人可以帮忙吗?

6 个答案:

答案 0 :(得分:4)

必须在派生类的构造函数体之前初始化基类;如果构造函数需要参数,则必须在初始化列表中提供这些参数:

Triangle(Point* A, Point* B, Point* C) :
    Polygon({A,B,C})
{}

请注意,这使用C ++ 11语法来创建临时向量;如果你被困在过去那么它会有点复杂:

static std::vector<Point*> make_points(Point* A, Point* B, Point* C) {
    std::vector<Point*> points;
    points.push_back(A);
    points.push_back(B);
    points.push_back(C);
}

Triangle(Point* A, Point* B, Point* C) :
    Polygon(make_points(A,B,C))
{}

或者为基类提供默认构造函数可能更容易(但可能更容易出错),然后在派生类构造函数中填充向量:

// In Polygon
Polygon() {} // constructed with no points
// pts must be "public" or "protected"

// In Triangle
Triangle(Point* A, Point* B, Point* C) {
    pts.push_back(A);
    pts.push_back(B);
    pts.push_back(C);
}

答案 1 :(得分:2)

您可以在addPoint()班级

中使用Polygon功能
class Polygon{
  public:
    vector<Point*> pts;
    Polygon(){}/// < The default constructor
    Polygon(vector<Point*> aPts) : pts(aPts) {}
    void addPoint(Point* p){
        pts.push_back(p);
    }
};
class Triangle : public Polygon{
public:
    Triangle(Point* A, Point* B, Point* C){// calls the default constructor
        addPoint(A);
        addPoint(B);
        addPoint(C);
    }
};

此外,大多数情况下,Point可以按值进行复制。我不知道你为什么用指针传递它。

答案 2 :(得分:1)

它试图调用Polygon类的默认构造函数,但由于你有自己的构造函数,因此默认的空构造函数不再存在。因此,您必须使用适当的参数调用Polygon's构造函数或定义一个空构造函数。

此外,您可以使用类似参数的Polygon's构造函数,这必须在Triangle类构造函数的初始化列表中完成。这样做是为了确保在创建base类对象之前正确初始化derived的成员。

答案 3 :(得分:1)

Polygon类中,定义一个带参数的构造函数vector。在这种情况下,编译器不会生成默认构造函数,因此 可以为Polygon构造函数传递参数。

Triangle中,您定义了一个带有三个参数的构造函数,但是您没有调用Polygon的构造函数。编译器尝试查找默认构造函数 - 一个没有参数的构造函数 - 但找不到一个,因此发出错误。

您无法像编写的那样在Polygon构造函数的末尾调用Triangle构造函数。 Polygon ctor必须在`Triangle ctor。

之前执行

尝试将ctor添加到Polygon,直接取代Point而不是vector,就像这样

class Polygon
{
public:
    vector<Point*> pts;
    Polygon(Point* A, Point* B, Point* C) {
        pts.push_back(A);
        pts.push_back(B);
        pts.push_back(C);
    }
};
class Triangle : public Polygon
{
public:
    Triangle(Point* A, Point* B, Point* C) : Polygon(A, B, C)
    {
    }
};

答案 4 :(得分:1)

应该从子类的构造函数的初始化列表中调用基类的构造函数。这就是导致代码中编译器错误的原因。下面的语法也是有效的,但它只是创建了一个Polygon的临时对象并使它失去了它:

Polygon(APts);

从设计的角度来看,通过按值复制矢量,您正在进行昂贵的操作 只是不要这样做。有一个无参数构造函数,然后填充构造函数。

class Polygon
{
public:
    vector<Point*> pts;  // can be made protected as well
    Polygon() {};
};
class Triangle : public Polygon
{
public:
    Triangle(Point* A, Point* B, Point* C) 
    {
        pts.push_back(A); pts.push_back(B); pts.push_back(C);
    }
};

如果你支持C ++ 11,那么可以更优雅地编写相同的代码。

class Polygon {
protected:
  vector<Point*> pts; 
public:
  Polygon(std::initializer_list<Point*>& v) : pts(v) {}
};

class Triangle : public Polygon {
public:
  Triangle (Point* p1, Point* p2, Point* p3) :
  Polygon({p1, p2, p3}) {}
};

class Square : public Polygon {
public:
  Square (Point* p1, Point* p2, Point* p3, Point* p4) :
  Polygon({p1, p2, p3, p4}) {}
};

用法:

Triangle t({x, y, z});
Square s({w, x, y, z});

答案 5 :(得分:1)

您必须将Polygon构造函数作为初始化列表的一部分,这意味着您需要构建一个初始化矢量的函数;

class Triangle : public Polygon
{
    // static method, not part of the object being constructed.
    static vector<Point*> BuildVector(Point* A, Point* B, Point* C) {
        vector<Point*> APts;
        APts.push_back(A); APts.push_back(B); APts.push_back(C);
        return APts;
    }

public:

    // Need to call Polygon's constructor before even entering our own;
    Triangle(Point* A, Point* B, Point* C) : Polygon(BuildVector(A, B, C))
    {
    }
};

请注意,通过将指针推入向量而不复制对象,您可能无法正确处理内存(谁将释放内存?),因此您可能希望使用某种类型的smart pointer,或者只是将点作为引用传递给构造函数。