PIMPL и распределение стека

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

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

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

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

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

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

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


person Anthony    schedule 11.07.2010    source источник
comment
Проблема с таким предупреждением заключается в том, что огромное количество операций приводит к выделению кучи. Создание std::vector тоже делает это. Или изменить размер одного. Компромисс заключается в том, насколько важно скрыть внутренности класса по сравнению с дополнительной производительностью, связанной с избеганием распределения кучи.   -  person jalf    schedule 11.07.2010


Ответы (2)


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

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

Я думал выпустить документацию с предупреждением рядом с конструкторами: «ВНИМАНИЕ: это приводит к выделению кучи» или что-то в этом роде.

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

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

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

person James McNellis    schedule 11.07.2010
comment
Хорошо, спасибо. Я все равно буду выглядеть как Fast Pimpl, потому что это выглядит интересно. - person Anthony; 11.07.2010

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

Ага.

Я думал выпустить документацию с предупреждением рядом с конструкторами: «ВНИМАНИЕ: это приводит к выделению кучи» или что-то в этом роде.

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

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

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

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

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

person Stephen    schedule 11.07.2010