я делаю что-то не так, если я использую кучу в C ++?

Чем больше Я читаю Что касается RAII, я понимаю, что использование стека — это способ убедиться, что код безопасен для исключений.

Означает ли это каждый раз, когда я делаю new() в моем коде я делаю что-то не так в том смысле, что есть лучший способ сделать это, используя принцип RAII?

0

Решение

Вы не обязательно делать что-то не так, если вы используете new, но стоит проверить, что вы все делаете правильно.

  • Результат new выражение должно быть немедленно помещено под контроль умного указателя, обычно передавая его прямо в конструктор.
  • Если этот умный указатель является shared_ptrтогда вы наверное делать неправильно. Вы, вероятно, должны использовать make_shared вместо. Есть некоторые ситуации, когда вы не должны (использование weak_ptr на большие объекты), а некоторые, где вы не можете (C ++ 03 без Boost).
  • Если вы используете delete тогда вы в значительной степени делаете это неправильно, если вы не пишете свой собственный класс интеллектуальных указателей. И даже в этом случае ваш умный указатель может использовать другой умный указатель для сохранения работы.
  • Это не обязательно, но если вы используете new исключительно потому, что объект «слишком большой для стека», подумайте о написании класса, который действует как дескриптор объекта, используя unique_ptr или же scoped_ptr управлять им, чтобы с точки зрения пользователя объекты, с которыми он имеет дело, были автоматическими переменными. Если вам это нравится, вы можете расширить его до полной идиомы. Даже если вам не нужен другой класс, рассмотрите функцию, которая создает объект и возвращает unique_ptr к нему, который вы можете затем назвать как auto foohandle = give_me_a_foo();, затем give_me_a_foo содержит new, но другой пользовательский код этого не делает, и вы поощряете практику автоматического добавления объектов в объекты RAII.

Существуют альтернативные стратегии управления ресурсами для RAII в C ++, но вы бы знали об этом, если бы использовали их, и это могло бы повлиять на то, что считается «неправильным».

2

Другие решения

Я думаю, что вы не до конца поняли, что на самом деле означает RAII. Динамическое распределение, точно так же, как другие программы, такие как файлы, подключения к базам данных и т. Д., Необходимы в программах. RAII фокусируется на том, как управлять этими ресурсами, и способ состоит в том, чтобы ресурсы управлялись объектами с автоматической продолжительностью хранения (либо в стеке, либо в качестве члена другого объекта).

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

2

Не за что. Если природа зверя (требования к распределению) действительно динамична, то в конечном итоге он будет либо возникать из кучи, либо из-за серьезного обмана указателя стека.

Лучшее, что вы можете сделать, — это использовать обертки, которые вам подходят. (Я могу сказать вам, как часто я использую std :: vector<> когда мне нужен динамический временный буфер, защищенный областью видимости). Это одна из самых идеальных причин для использования хорошо поддерживаемых и разработанных библиотек, таких как STL и т. Д. И в отличие от C # или Java, его предсказуемость, которая имеет огромное значение, когда действительно необходимо.

1

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

0
По вопросам рекламы [email protected]