不确定标题的措辞是否正确,但这里是:
我有一个地图类,其中包含一个包含MapEntitys的向量。 MapEntity是继承Factory,Farm和其他3个类的类。
这五个类都应该每隔几秒“勾选”一次,此时它们都将为每个类单独执行一个函数,但只有map类应该能够“勾选”它们。
我如何在C ++中支持这种类型的封装?朋友?我应该使用公共方法而不是滥用方法吗? (虽然我更喜欢适当的封装以获得良好的实践,即使这些代码不会被重新分发)
再次,我意识到这措辞不是很好,所以请和我一起露面。先谢谢你,
答案 0 :(得分:2)
从语法上讲,你可以使用任何一种。
但是,如果要从外部“勾选” MapEntities ,则tick
方法应该是其公共方法的一部分。实际上,它应该是MapEntity
类的虚拟公共方法。
是的,公共方法是适当的封装。他们告诉您班级的用户它能做什么。在这种情况下,用户是Map
类,它可以tick
MapEntities。
只有当MapEntities
设计仅由Map
使用时,才应考虑其他解决方案(朋友,匿名命名空间等)。
答案 1 :(得分:2)
您可以使用friend
,但我认为最好不要对可以“勾选”MapEntity类的内容施加任何限制。
在代码中加入人为限制通常被认为是不好的做法。即使您只希望您的地图类能够立即调用此函数,但这可能会在将来发生变化。
答案 2 :(得分:0)
使用friend
实际上会降低封装程度,因为您的地图类会看到MapEntities
的任何私有,而不仅仅是tick
方法。
答案 3 :(得分:0)
在我看来,您的任务看起来像设计模式访客描述。
class Visitor;
class MapEntity
{
public:
virtual void tick(Visitor &v) = 0;
};
class Factory: public MapEntity
{
public:
void accept(Visitor &v);
// ...
};
class Farm: public MapEntity
{
public:
void tick(Visitor &v);
// ...
};
class Mill: public MapEntity
{
public:
void tick(Visitor &v);
// ...
};
class Visitor
{
public:
virtual void visit(Factory *e) = 0;
virtual void visit(Farm *e) = 0;
virtual void visit(Mill *e) = 0;
};
void Factory::tick(Visitor &v) { v.visit(this); }
void Farm::tick(Visitor &v) { v.visit(this); }
void Mill::tick(Visitor &v) { v.visit(this); }
class SomeVisitor: public Visitor
{
void visit(Factory *e) { /* ... */ };
void visit(Farm *e) { /* ... */ };
void visit(Mill *e) { /* ... */ };
};
class OtherVisitor: public Visitor { /* ... */ };
客户代码:
MapEntity *enities[];
// ...
SomeVisitor v1;
OtherVisitor v2;
for (int i = 0; i < N; ++i)
{
entities[i].tick(v1);
}
for (int i = 0; i < N; ++i)
{
entities[i].tick(v2);
}