Инкапсуляция в классе композиции C ++ - PullRequest
0 голосов
/ 06 марта 2011

Не уверен, что заголовок сформулирован правильно, но здесь идет речь:

У меня есть класс карты, который содержит вектор, содержащий MapEntitys.MapEntity - это класс, от которого унаследованы Фабрика, Ферма и 3 других класса.

Оба эти 5 класса должны быть отмечены галочкой каждые несколько секунд, после чего все они будут выполнять функции, индивидуальные для каждого классано только класс карты должен иметь возможность пометить их.

Как бы я поддерживал этот тип инкапсуляции в C ++?Друзья?Должен ли я просто использовать публичные методы, а не злоупотреблять этими методами?(Хотя я бы предпочел правильную инкапсуляцию для хорошей практики, даже если этот код не будет перераспределен)

Опять же, я понимаю, что это не очень хорошо сформулировано, поэтому, пожалуйста, держитесь со мнойЗаранее спасибо, эл.

Ответы [ 4 ]

2 голосов
/ 06 марта 2011

Вы можете использовать friend, но я думаю, что лучше не накладывать никаких ограничений на то, что может пометить ваши классы MapEntity.

Обычно считается плохой практикой устанавливать искусственные ограничения в вашем коде. Даже если вы хотите, чтобы класс карты мог вызывать эту функцию прямо сейчас, это может измениться в будущем.

2 голосов
/ 06 марта 2011

Синтаксически вы можете использовать любой из них.

Однако, если MapEntities должны быть "помечены" извне, метод tick должен быть частью их открытых методов. На самом деле, это должен быть виртуальный публичный метод класса MapEntity.

И да, публичные методы - это правильная инкапсуляция. Они говорят пользователю вашего класса, что он может сделать. В этом случае пользователь является классом Map и может tick MapEntities.

Вам следует рассмотреть другие решения (друзья, анонимные пространства имен и т. Д.), Только если MapEntities предназначены для использования только Map.

0 голосов
/ 06 марта 2011

На мой взгляд, ваша задача выглядит как описание посетителя шаблона дизайна.

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);
}
0 голосов
/ 06 марта 2011

Использование friend фактически снизит степень инкапсуляции, поскольку ваш класс карты будет видеть любые ряды MapEntities, а не только метод tick.

...