组合类 C++ 中的封装

发布于 2024-10-20 05:45:34 字数 226 浏览 2 评论 0原文

我有一个地图类,其中包含一个包含 MapEntity 的向量。 MapEntity是Factory、Farm和其他3个类继承的类。

这 5 个类都应该每隔几秒“勾选”一次,此时它们都会为每个类执行单独的功能,但只有地图类应该能够“勾选”它们。

我如何在 C++ 中支持这种类型的封装?朋友们?我应该只使用公共方法而不是滥用这些方法吗? (尽管我更喜欢适当的封装以实现良好的实践,即使此代码不会被重新分发)。

I have a map class, which contains a vector containing MapEntitys. MapEntity is a class of which Factory, Farm and 3 other classes are inherited from.

These 5 classes both should be "ticked" every few seconds, at which point they will all do a function individual to each class, but only the map class should be able to "tick" them.

How would I support this type of encapsulation in C++? Friends? Should I just use public methods and not misuse the methods? (Although I would prefer proper encapsulation for good practice, even though this code will not be re-distributed).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

仙女 2024-10-27 05:45:34

从语法上讲,你可以使用其中任何一个。

但是,如果要从外部“勾选”MapEntities,则 tick 方法应该是其公共方法的一部分。实际上,它应该是MapEntity类的虚拟公共方法。

是的,公共方法是正确的封装。他们告诉你的类的用户它可以做什么。在本例中,用户是Map 类,它可以tick MapEntities。

仅当MapEntities设计仅供Map使用时,您才应考虑其他解决方案(友元、匿名命名空间等)。

Syntactically you could use any of that.

However, if MapEntities are to be "ticked" from outside, the tick method should be part of their public methods. Actually, it should be a virtual public method of the MapEntity class.

And yes, public methods are proper encapsulation. They tell the user of your class what it can do. In this case, the user is the Map class and it can tick MapEntities.

You should consider other solutions (friends, anonymous namespaces etc.) only if MapEntities are designed to be used only by Map.

夏日浅笑〃 2024-10-27 05:45:34

您可以使用 friend,但我认为最好不要对可以“勾选”您的 MapEntity 类的内容施加任何限制。

在代码中人为限制通常被认为是不好的做法。即使您现在只希望地图类能够调用此函数,但这在将来可能会发生变化。

You could use friend, but I think it's better to not put any restriction on what can 'tick' your MapEntity classes.

It's generally considered bad practice to put artificial limitations in your code. Even though you only want your map class to be able to call this function right now, this might change in the future.

请别遗忘我 2024-10-27 05:45:34

使用 friend 实际上会降低封装程度,因为您的地图类会看到 MapEntities 的任何私有属性,而不仅仅是 tick 方法。

Using friend would actually lower the degree of encapsulation, since your map class would see any privates of MapEntities, not only the tick method.

暗藏城府 2024-10-27 05:45:34

在我看来,您的任务看起来像设计模式访客描述。

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);
}

In my opinion your task looks like design-pattern visitor description.

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  { /* ... */ };

client code:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文