Поместить все методы в определение класса
Когда я использую идиому 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, я не думаю, что имеет значение, определены методы в теле Беса или нет. Мне лично нравятся их определения снаружи, потому что легко увидеть, что действительно важно (например, переменные-члены и список методов).