Перечислить проблему «копирования» - PullRequest
2 голосов
/ 08 апреля 2010

У меня есть класс, назовем его A. Он имеет enum (E) и метод Foo (E e), в котором получает E в аргументах. Я хочу написать оболочку (декоратор) W для A. Так что у него будет свой метод Foo (A :: E). Но я хочу иметь некоторую инкапсуляцию, поэтому этот метод должен быть определен как Foo (F f), где F - это другое перечисление, определенное в W, которое можно преобразовать в A :: E. Например:

class A
{
  public:
    enum E { ONE, TWO, THREE };
    void Foo(E e);  
};

class B
{
  //enum F; // ???
  void Foo(F f)
  {
    a_.Foo(f);
  }

  private:
    A a_;
};

Как определить F? Я не хочу копировать значение следующим образом:

enum F { ONE = A::ONE, TWO = A::TWO, THREE = A::THREE };

потому что это потенциальная ошибка в ближайшем объекте. Это определение типа:

typedef A::E F;

это лучшее решение? Это законно?

Ответы [ 2 ]

1 голос
/ 09 апреля 2010

Проблема с typedef в том, что он не заставляет A уходить. Вы не сможете сказать F f = B::ONE;, потому что B :: ONE не существует. Вам все равно придется использовать A :: ONE и т. Д. Насколько я понимаю, это не то, что вам нужно.

Для того, на что вы, похоже, рассчитываете, создание нового перечисления в B, вероятно, будет лучшим выбором. Единственное, о чем следует помнить: 1) вам нужно будет ввести приведение между A :: E и B :: F и 2) изменения в одном перечислении должны быть отражены в другом.

Хотя нет необходимости копировать значения так, как вы это делаете. Если A :: E было:

enum E { ONE = 4, TWO = 7, THREE, FOUR, FIVE };

Вы можете скопировать и вставить это, чтобы создать B :: F:

enum F { ONE = 4, TWO = 7, THREE, FOUR, FIVE };

Однако недостатком этого метода копирования и вставки является то, что если я тогда решу изменить A :: TWO на десять, я должен быть уверен, что изменил B :: TWO. Если бы вы определили B :: F так, как вы показали (ONE = A :: ONE ...), это не было бы проблемой, но это было бы немного больше работы.

0 голосов
/ 08 апреля 2010

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

...