PIMPL и выделение стека

Таким образом, я думал о PIMPL и складываю выделение. Я писал библиотеку и решил использовать PIMPL для сокрытия члена парламента, не занимающего официального поста класса. Это означает, что мне объявили бы класс как это

class Foo {
private:
    class Handle;
    std::tr1::shared_ptr<Handle> handle;
public:
    Foo();
};

Это является довольно прямым. Но затем в конструкторе Вы делаете это

Foo::Foo() : handle(new Handle()) {}

Таким образом, когда кто-то пользующийся моей библиотекой создает Нечто на стеке, они по существу делают выделение "кучи" так или иначе. Действительно ли это - компромисс, с которым необходимо жить при использовании PIMPL? Я думал о выпуске документации с предупреждением рядом с конструкторами: "ПРЕДУПРЕЖДЕНИЕ: Это приводит к выделению "кучи"" или somesuch.

Моя другая мысль состояла в том, чтобы иметь все классы, которые подвергнуты реализации как чистые виртуальные интерфейсы и целый набор статических методов фабрики, возвратив интеллектуальные указатели. Это также означает выделение "кучи", но нет никакого приема к нему.

Какие-либо мысли или предложения? Я чрезмерно внимателен к программистам, пользующимся моей библиотекой?

5
задан Anthony 11 July 2010 в 02:33
поделиться

2 ответа

Это компромисс, с которым вам приходится мириться при использовании PIMPL?

Фактически, да, хотя есть методы, такие как те, которые обсуждались Хербом Саттером в "The Fast Pimpl Idiom », который можно использовать для устранения или ускорения выделения кучи за счет большей сложности.

Я подумал о выпуске документации с предупреждением рядом с конструкторами: «ПРЕДУПРЕЖДЕНИЕ: это приводит к распределению в куче» или что-то подобное.

Только если это необходимо (то есть, только если ваши пользователи будут удивлены тем фактом, что ваш класс выполнил выделение кучи). Многие классы выполняют распределение кучи, в том числе многие из них в стандартной библиотеке C ++ (например, все контейнеры).

Не слишком ли я внимателен к программистам, использующим мою библиотеку?

Возможно :-). Если у вас нет высоких требований к производительности для вашего класса или вы не ожидаете, что экземпляры вашего класса будут создаваться и уничтожаться очень часто, я бы не стал слишком беспокоиться об этом. Конечно, если у вас есть серьезные требования к производительности, pimpl может быть не лучшим выбором.

4
ответ дан 14 December 2019 в 04:29
поделиться

Поэтому, когда кто-то, используя мою библиотеку, создает Foo на стеке, он в любом случае выполняет выделение кучи. Это тот компромисс, с которым вам приходится мириться при использовании PIMPL?

Да.

Я подумал о том, чтобы выпустить документацию с предупреждением рядом с конструкторами: "WARNING: This results in a heap allocation" или что-то в этом роде.

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

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

Да, это немного более очевидно для пользователя, но опять же, вероятно, не стоит беспокоиться об этом.

Есть какие-нибудь мысли или предложения? Не слишком ли я забочусь о программистах, использующих мою библиотеку?

Это компромисс, но если ваш класс достаточно сложен, чтобы действительно извлечь пользу из идиомы pimpl, вы, вероятно, можете считать, что выделение кучи - это нормально. Если бы я использовал вашу библиотеку, это, вероятно, не беспокоило бы меня.

4
ответ дан 14 December 2019 в 04:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: