зачем мне запрещать выделение в куче? - PullRequest
5 голосов
/ 19 августа 2010

Недавно я много читал о «предотвращении выделения кучи для класса» (см. этот вопрос ).

Я смог понять "как" , но теперь я не могу понять "почему" кто-то хотел бы это сделать.

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

Вкратце: «Почему я могу запретить пользователям создавать объекты моего класса в куче?»

Ответы [ 6 ]

13 голосов
/ 19 августа 2010

Некоторые классы имеют смысл, только если объекты создаются в стеке. Например, Boost scoped_ptr или lock_guard .

5 голосов
/ 19 августа 2010

Главным образом потому, что объекты, выделенные в стеке, автоматически очищаются при выходе из области видимости, таким образом удаляя большой класс ошибок, а именно ошибок распределения памяти.

4 голосов
/ 19 августа 2010

Кажется, я пойду против течения (поэтому я ожидаю снижения голосов, но, пожалуйста, оставьте комментарий, чтобы указать причину).

Я не вижу причин запрещать выделение кучи, в основном потому, что мне не нравится повторять потенциальное использование созданных мной классов.

Как правило, я стараюсь как можно меньше ограничивать использование моих классов. Это означает как можно меньше предположений. Ничто так не сводит с ума, как неспособность делать то, что вы хотите, просто потому, что это было запрещено ... по неизвестным или просто неправильным причинам (обозначая суеверные / ошибочные убеждения автора библиотеки).

Кроме того, прагматизм учит, что на самом деле невозможно предотвратить что-либо в C ++. Например, некоторые люди говорили об охране -> что, если я хотел бы создать суперкласс (который удобно добавляет логирование)? Тогда я бы поставил охранный класс в качестве атрибута, и даже если его (исходный класс) оператор new является закрытым, мой суперкласс может быть создан в куче, если он каким-либо образом не копирует механизм.

Так что, что касается меня, дело не в том, почему или как. Я просто не играю со схемами выделения памяти в библиотечном коде, пользователь может использовать то, что ему удобнее.

2 голосов
/ 19 августа 2010

Обычно хорошей идеей является предотвращение неожиданного использования класса. Например, рассмотрим классы гвардии, которые полагаются на технику RAII. Они должны быть размещены в стеке, и они выполняют свою работу, когда выходят из области видимости. Никто не ожидает, что пользователи будут размещать объекты защиты в куче, поэтому это явно запрещено.

Лучше явно, чем неявно. Херб Шуттер говорит, что должно быть трудно неправильно использовать ваш класс (выделение в куче) и очень легко использовать его правильно (в стеке).

1 голос
/ 19 августа 2010

Распределение стека происходит быстрее (поиск места не требуется).

0 голосов
/ 19 августа 2010

Для определенных классов очень маленьких объектов - рассмотрите трехмерные точки в геометрическом движке - их выделение по отдельности в куче является рецептом для создания висячих указателей и введения огромного количества накладных расходов - однако они жизненно необходимы во многих расчеты

Таким образом, общий механизм состоит в том, чтобы использовать шаблон с наименьшим весом в объектах, которые на самом деле содержат набор трехмерных точек, например описание некоторой геометрической сущности, и разрешать их использование в куче в качестве промежуточных результатов вычислений.

Теперь, при этом, необходимо принять особые меры предосторожности, чтобы избежать ненужного копирования данных между реализациями flyweight, например, ListOf3DPoints и куча выделенных трехмерных точек, которые используются для промежуточных результатов.

В общем, я обнаружил несколько случаев, когда я совмещал шаблон «навесного веса» с возможностями выделения кучи для достижения оптимальных результатов - навесное весовое пространство обеспечивает постоянное хранилище, распределения кучи позволяют мне выполнять манипуляции на уровне элементов без необходимости генерации еще один легкий вес

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...