Таким образом, я думал о PIMPL и складываю выделение. Я писал библиотеку и решил использовать PIMPL для сокрытия члена парламента, не занимающего официального поста класса. Это означает, что мне объявили бы класс как это
class Foo {
private:
class Handle;
std::tr1::shared_ptr<Handle> handle;
public:
Foo();
};
Это является довольно прямым. Но затем в конструкторе Вы делаете это
Foo::Foo() : handle(new Handle()) {}
Таким образом, когда кто-то пользующийся моей библиотекой создает Нечто на стеке, они по существу делают выделение "кучи" так или иначе. Действительно ли это - компромисс, с которым необходимо жить при использовании PIMPL? Я думал о выпуске документации с предупреждением рядом с конструкторами: "ПРЕДУПРЕЖДЕНИЕ: Это приводит к выделению "кучи"" или somesuch.
Моя другая мысль состояла в том, чтобы иметь все классы, которые подвергнуты реализации как чистые виртуальные интерфейсы и целый набор статических методов фабрики, возвратив интеллектуальные указатели. Это также означает выделение "кучи", но нет никакого приема к нему.
Какие-либо мысли или предложения? Я чрезмерно внимателен к программистам, пользующимся моей библиотекой?
Это компромисс, с которым вам приходится мириться при использовании PIMPL?
Фактически, да, хотя есть методы, такие как те, которые обсуждались Хербом Саттером в "The Fast Pimpl Idiom », который можно использовать для устранения или ускорения выделения кучи за счет большей сложности.
Я подумал о выпуске документации с предупреждением рядом с конструкторами: «ПРЕДУПРЕЖДЕНИЕ: это приводит к распределению в куче» или что-то подобное.
Только если это необходимо (то есть, только если ваши пользователи будут удивлены тем фактом, что ваш класс выполнил выделение кучи). Многие классы выполняют распределение кучи, в том числе многие из них в стандартной библиотеке C ++ (например, все контейнеры).
Не слишком ли я внимателен к программистам, использующим мою библиотеку?
Возможно :-). Если у вас нет высоких требований к производительности для вашего класса или вы не ожидаете, что экземпляры вашего класса будут создаваться и уничтожаться очень часто, я бы не стал слишком беспокоиться об этом. Конечно, если у вас есть серьезные требования к производительности, pimpl может быть не лучшим выбором.
Поэтому, когда кто-то, используя мою библиотеку, создает Foo на стеке, он в любом случае выполняет выделение кучи. Это тот компромисс, с которым вам приходится мириться при использовании PIMPL?
Да.
Я подумал о том, чтобы выпустить документацию с предупреждением рядом с конструкторами: "WARNING: This results in a heap allocation" или что-то в этом роде.
Я бы счел это слишком агрессивным комментированием :) Если ваш класс настолько критичен к производительности, возможно, вам следует избегать идиомы PIMPL. Если вы представляете число, это может вызвать беспокойство и заслуживает внимания. Если вы скрываете реализацию соединения с базой данных, это не стоит комментария :)
Другая моя мысль заключалась в том, чтобы все классы, которые открыты для реализации, были чистыми виртуальными интерфейсами и целой кучей статических фабричных методов, возвращающих умные указатели. Это также означает выделение кучи, но в этом нет никакой хитрости.
Да, это немного более очевидно для пользователя, но опять же, вероятно, не стоит беспокоиться об этом.
Есть какие-нибудь мысли или предложения? Не слишком ли я забочусь о программистах, использующих мою библиотеку?
Это компромисс, но если ваш класс достаточно сложен, чтобы действительно извлечь пользу из идиомы pimpl, вы, вероятно, можете считать, что выделение кучи - это нормально. Если бы я использовал вашу библиотеку, это, вероятно, не беспокоило бы меня.