[英]Encapsulation in a Composition Class C++
我有一个地图类,其中包含一个包含MapEntitys的向量。 MapEntity是继承自Factory,Farm和其他3个类的类。
这5个类都应每隔几秒钟被“滴答”一声,这时它们都将对每个类单独执行一个功能,但是只有map类才能“勾号”它们。
我如何在C ++中支持这种类型的封装? 朋友? 我应该只使用公共方法而不滥用这些方法吗? (尽管为了更好的实践,我更喜欢适当的封装,即使不会重新分发此代码)。
从语法上讲,您可以使用任何一种。
但是,如果要从外部“勾选” MapEntities ,则tick
方法应该是其公共方法的一部分。 实际上,它应该是MapEntity
类的虚拟公共方法。
是的,公共方法是正确的封装。 他们告诉班级的用户它可以做什么。 在这种情况下,用户是Map
类,并且可以在MapEntities上tick
。
仅当MapEntities
设计为仅由Map
使用时,才应考虑其他解决方案(朋友,匿名名称空间等)。
您可以使用friend
,但我认为最好不要对可以“勾选” MapEntity类的内容施加任何限制。
将人为的限制放入代码中通常被认为是不好的做法。 即使您只希望地图类现在能够调用此函数,但将来可能会改变。
实际上,使用friend
会降低封装的程度,因为您的地图类会看到MapEntities
所有MapEntities
,而不仅是tick
方法。
我认为您的任务类似于设计模式的访客描述。
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.