子类构造函数
Subclass Constructors
我在C++中处理子类时遇到问题。我有一个多边形的类和一个三角形的子类。我希望能够通过传递点*(这是一个自定义类)的向量来声明多边形,通过传递三个点*s来声明三角形。
我的理解是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);
}
};
然而,在三角形构造函数的左括号上,我得到了错误:
error: no matching function call to 'Polygon::Polygon()'
有人能帮忙吗?
基类必须在派生类的构造函数主体之前初始化;如果构造函数需要参数,则必须在初始化程序列表中提供这些参数:
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);
}
您可以在Polygon
类中拥有addPoint()
函数
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
在大多数情况下都可以通过值进行复制。我不知道你们为什么用指针传过去。
它试图调用Polygon
类的默认构造函数,但由于您有自己的构造函数,默认的空构造函数已不存在。因此,您必须使用正确的参数调用Polygon's
构造函数,或者定义一个空的构造函数。
另外,不能用这样的参数来创建Polygon's
构造函数,这必须在Triangle
类构造函数的初始化列表中完成。这样做是为了确保在创建derived
类对象之前正确初始化base
的成员。
在Polygon
类中,定义一个采用参数vector
的构造函数。在这种情况下,编译器不会生成默认构造函数,因此必须向Polygon
构造函数传递参数。
在Triangle
中,您定义了一个使用三个参数的构造函数,但不调用Polygon
的构造函数。编译器试图找到一个默认构造函数——一个没有参数的构造函数——但找不到,因此会发出错误。
不能像您所写的那样在Triangle
构造函数的末尾调用Polygon
构造函数。Polygon
ctor必须在`Triangle ctor之前执行。
尝试在Polygon
中添加一个直接获取三个Point
的ctor,而不是在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)
{
}
};
您必须调用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))
{
}
};
请注意,在不复制对象的情况下将指针推入向量,可能会导致内存处理不正确(谁来释放内存?),因此您可能希望使用某种类型的智能指针,或者只是将点作为引用传递到构造函数中。
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});
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 参数包构造函数在类模板中隐藏用户定义的转换
- 具有已删除移动和复制构造函数的类的就地构造
- 创建一个没有复制构造函数的类的 std::vector 的 std::vector
- C++构造函数和类?
- 在 C++ 中,默认情况下构造函数为类的数据成员提供的值是多少?
- 如何在其他类中使用参数化构造函数制作类的对象?
- 具有值包装器的可变参数模板构造函数的类构造函数优先级
- 如何使用私有构造函数对类进行单元测试?
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- 从作为模板参数传递给构造函数的类继承,或者从它们继承
- 继承的构造函数忽略类内初始化
- 模板和隐式构造函数的类定义之外的友元声明
- 具有字符串文本构造函数的类不适用于 const 引用初始化
- C++ - 从另一个类构造函数调用类构造函数
- 定义结构中没有默认构造函数的类
- 我可以将 std::move 与不提供 move 构造函数的类一起使用吗?
- 是否可以默认初始化具有已删除默认构造函数的类类型
- C++具有移动和复制构造函数的类中的代码重复
- 没有默认构造函数的类对象的值初始化