" has-a"的缺点关系,C ++

时间:2016-04-21 12:13:57

标签: c++

我的情况类似于以下情况。

class Point
{
    void setCoord(int x, int y)
    {
        this->x = x;
        this->y = y;
    }

    private:
        int x,y;
}

class Line
{
    public:
        Point *p1;
        Point *p2;
}

Line构造函数和析构函数看起来像

Line::Line()
{
    p1 = new Point();
    p2 = new Point();
}

Line::~Line()
{
    delete p1;
    delete p2;    
}

现在,在应用程序中可以调用内部对象Point的方法。

int main()
{
    Line line;
    line.p1->setCoord(x1,y1);
    line.p2->setCoord(x2,y2);
}

我收到了一些建议1)" has-a"关系是坏的,2)指向p1和p2的指针,可以替换。

我同意第二点是有效的。我们可以阻止指针被应用程序替换吗?

但是,我不相信第一点。是"有一个"包含同一内部类的多个实例的类的关系不好?在这种情况下,有没有更好的方法来模拟类?

修改

根据对此问题和答案的评论对问题进行一些澄清。 Point的成员x和y不能公开,只能通过公共函数setCoord进行操作。

即使我用点p1,p2替换Point * p1,* p2,也可以执行line.p1 = Point()并更改p1和p2。也需要防止这种情况。

2 个答案:

答案 0 :(得分:3)

首先,带有两个点的线段对于带有指针的类来说是个坏例子。很难想象你不希望Point s作为值成员而不是指针的情况。

在更一般的意义上,要表示调用代码不应该更改指针,将它们设为私有并创建返回对数据的引用的getter方法。在适用的地方添加const

class ResourceOwner
{
private:
    Resource *r;
public:
    inline Resource& GetResource() { return *r; }

    // implement rule of 5
};

答案 1 :(得分:3)

  

在这种情况下,有没有更好的方法来模拟类?

由于Line拥有Point,因此它应该只有两个值:

class Line
{
public:
    Point p1, p2;
};

现在Point不变量保证一条线实际上由两个点组成,没有人可以放入例如空指针。没有其他任何内容需要强制执行,将Point替换为任何其他Point仍然有效Line

虽然我们处于此状态,但Point也不必要复杂。这是一个更好的版本:

class Point
{
public:
    int x, y;
};

在此处使用struct可以使代码更加清晰。