为什么我不能在这里使用成员初始化列表?

时间:2012-01-09 17:45:07

标签: c++

我刚刚创建了一个“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;
}

3 个答案:

答案 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::Pointp1分别)调用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 &);,或者更好的是,将其完全删除,因为它与隐式定义的完全相同。同样,定义自己的析构函数是没有意义的,除非它需要做某事,或者需要虚拟或非公共。