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

Disadvantages of "has-a" relationship, C++

本文关键字:C++ 缺点 has-a 关系      更新时间:2023-10-16

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

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的指针可以替换。

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

但是,我不相信第一点。"has-a"关系对于包含同一内部类的多个实例的类是否有害?在这种情况下,有没有更好的方法来对类进行建模?

编辑:

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

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

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

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

class ResourceOwner
{
private:
    Resource *r;
public:
    inline Resource& GetResource() { return *r; }
    // implement rule of 5
};

在这种情况下,有没有更好的方法来对类进行建模?

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

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

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


当我们在做这件事时,Point也是不必要的复杂。这是一个更好的版本:

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

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