Обходные пути для заранее объявленной проблемы перечисления классов? - PullRequest
4 голосов
/ 07 декабря 2009

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

У меня проблема с классами, которые содержат публичные перечисления. Эти перечисления не могут быть объявлены заблаговременно, поэтому у меня нет выбора, кроме как включить заголовок класса. Например:

// Foo.h

class Foo
{
public:
  enum Type
  {
    TYPE_A,
    TYPE_B,
  };
  ...
};

// Bar.h

#include "Foo.h" // For Foo::Type

class Bar
{
public:
  void someFunction(Foo::Type type);
  ...
};

Итак, я ищу способы избежать этого и могу думать только о следующем:

Переместить перечисления классов в отдельное пространство имен типов

// FooTypes.h

namespace FooTypes
{
  enum Type
  {
    TYPE_A,
    TYPE_B,
  };
}

// Bar.h

#include "FooTypes.h"

class Bar
{
public:
  void someFunction(FooTypes::Type type);
  ...
};

Используйте int вместо перечисления

// Bar.h

class Bar
{
public:
  void someFunction(int type);
  ...
};

Что я пропустил? Как другие люди обходят это ограничение (не имея возможности пересылать объявления перечислений.)

Ответы [ 3 ]

3 голосов
/ 07 декабря 2009

Поместите перечисление в класс, содержащий PIMPL.

2 голосов
/ 07 декабря 2009

Поместите перечисление в его собственный тип:

struct FooEnum
{
  enum Type
  {
    TYPE_A,
    TYPE_B,
  };
};

Тогда Foo и Bar могут одновременно обращаться к FooEnum::Type, и Bar.h не обязательно включать Foo.h.

0 голосов
/ 08 декабря 2009

Я бы сказал, что перечисления - плохая идея для начала, но в целом для констант / многих вещей, таких как константы в C ++, ни одна из которых не является достаточно константой и у всех есть проблемы. Мне нравится помещать его в структуру, тогда классы, использующие его, наследуют от структуры.

Я бы также сказал, что идиома прыщей плохая. На самом деле я уверен, что это плохой способ делать вещи. Это то, что работает, но неуклюже и немного глупо. Этого также легко избежать, и единственная причина, по которой это происходит, заключается в том, что люди используют еще один неправильный выбор дизайна.

Обычно кто-то просто привязывает ООП к классу, который он задумал, чтобы быть конкретным. Затем вы получаете случай смешанного наследования и множество проблем, которые он вызывает, таких как супер медленное время компиляции. Вместо этого рассмотрите чистые виртуальные базовые классы, а затем напишите свои библиотеки для этого, чтобы избежать шаблонов и избежать проблемы прямого объявления. Не для всего, но определенно для случаев, когда вы генерируете код для большого количества классов.

...