我的情况类似于以下情况。
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。也需要防止这种情况。
答案 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
可以使代码更加清晰。