繁体   English   中英

组合类C ++中的封装

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM