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

Когда я использую идиому pimpl, стоит ли помещать все определения методов в определение класса? Например:

// in A.h

class A {
   class impl;
   boost::scoped_ptr<impl> pimpl;
public:
   A();
   int foo();
}

// in A.cpp

class A::impl {
   // method defined in class
   int foo() {
       return 42;
   }

   // as opposed to only declaring the method, and defining elsewhere:
   float bar();
};

A::A() : pimpl(new impl) { }
int A::foo() {
   return pimpl->foo();
}

Насколько я знаю, единственные проблемы с помещением определения метода в определение класса состоят в том, что (1) реализация видна в файлах, которые включают определение класса, и (2) компилятор может сделать метод встроенным.

В этом случае это не проблемы, поскольку класс определен в личном файле, а встраивание не имеет никакого эффекта, поскольку методы вызываются только в одном месте.

Преимущество помещения определения в класс состоит в том, что вам не нужно повторять сигнатуру метода.

Так это нормально? Есть ли другие проблемы, о которых нужно знать?

4 ответа

Решение

Я думаю, что вы ответили на свой вопрос: оба решения эквивалентны.

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

В конце концов, я считаю, что это просто вопрос вкуса.

Преимущества:

  • весь код класса локализован

Недостатки:

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

Обычно я не добавляю методы к внутреннему классу Impl, но не вижу никаких проблем, если вы определите методы встроенными. Это кажется мне намного более читабельным, чем отдельное объявление и определение.

Указывает ли компилятор методы, зависит от компилятора и переданных параметров.

В случае идиомы pimpl, я не думаю, что имеет значение, определены методы в теле Беса или нет. Мне лично нравятся их определения снаружи, потому что легко увидеть, что действительно важно (например, переменные-члены и список методов).

Другие вопросы по тегам