我刚刚创建了一个“Point”类,并且正在开发一个“Line”类,它有两个Point对象(Point startpoint和Point endpoint)作为数据成员。我在我的Line类中创建了一个构造函数,它接受两个Point对象作为参数,最初创建它如下:
Line(const Point& p1, const Point& p2)
{
startpoint = p1;
endpoint = p2;
}
一切都很好,但后来我决定使用成员初始化列表而不是将成员分配到正文中的p1和p2,只是因为......但是当我将其更改为:
Line(const Point& p1, const Point& p2): startpoint(p1), endpoint(p2)
{
}
我得到一个错误,说“没有构造函数的实例”Point :: Point“匹配参数列表”并且不明白这意味着什么。
为什么成员初始化列表不能在这里工作?
感谢。
编辑:对不起,我不知道我的积分课的细节是否相关:
// Point.h
class Point
{
private:
double x;
double y;
public:
Point();
Point(Point& p);
Point(double x1, double y1);
~Point();
double X() const;
double Y() const;
void X(double newx);
void Y(double newy);
};
// Point.cpp
#include "Point.h"
Point::Point(): x(0), y(0)
{
}
Point::Point(Point& p)
{
x = p.x;
y = p.y;
}
Point::Point(double x1, double y1): x(x1), y(y1)
{
}
Point::~Point()
{
}
double Point::X() const
{
return x;
}
double Point::Y() const
{
return y;
}
void Point::X(double newx)
{
x = newx;
}
void Point::Y(double newy)
{
y = newy;
}
答案 0 :(得分:10)
成员初始化取决于具有公共拷贝构造函数的Point
,因为您明确调用了Point::Point(const Point&)
。
如果不存在或无法访问,则无法调用它。如果你不能调用它,那不是因为初始化列表不起作用。
如果第一个版本有效,大概Point
有一个可访问的赋值运算符。
要确认,现在您已粘贴Point
的来源,复制构造函数应如下所示:
Point::Point(const Point &other) : x(other.x), y(other.y) {}
(您也可以使用初始化列表)。
关键的变化是参数必须是const
引用:这禁止在复制时意外损坏源对象。
答案 1 :(得分:3)
在
Line(const Point& p1, const Point& p2): startpoint(p1), endpoint(p2)
您正在使用Point::Point
(p1
分别)调用p2
,其类型为const Point&
,即您承诺永远不会更改提供给Line::Line
的参数。现在,让我们来看看你的Point
课程。具有匹配数量的参数的唯一方法是
Point(Point& p);
这需要Point&
,可以在Point::Point(Point&)
内修改。因此,您无法在p1
(或p2
)传递,因为您已经承诺永远不会更改它。
制作你的构造函数
Point(const Point& p);
您可以像使用初始化列表一样使用初始化列表。
答案 2 :(得分:0)
Point(Point& p);
您的复制构造函数需要对const
进行非Point
引用。这意味着您无法初始化初始化列表所需的const
引用中的点。分配有效,因为您尚未实现自己的复制赋值运算符,因此使用了隐式赋值运算符。
您应该将复制构造函数更改为Point(Point const &);
,或者更好的是,将其完全删除,因为它与隐式定义的完全相同。同样,定义自己的析构函数是没有意义的,除非它需要做某事,或者需要虚拟或非公共。