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