PIMPL и выделение стека - PullRequest
5 голосов
/ 11 июля 2010

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

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

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

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

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

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

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

Ответы [ 2 ]

4 голосов
/ 11 июля 2010

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

Да.

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

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

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

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

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

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

4 голосов
/ 11 июля 2010

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

По сути, да, хотя существуют методы, подобные тем, которые обсуждались Хербом Саттером в «Быстрая идиома», , которые можно использовать для устранения или ускорения выделения кучи за счет большая сложность.

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

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

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

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

...