Локальная переменная или указатель - PullRequest
3 голосов
/ 28 сентября 2011

Учитывая класс в любой произвольной среде C ++, как узнать, нужно ли создавать простой объект в стеке или указатель на объект в куче?

Предположим, что функция принимает аргумент в виде ссылочной (&) переменной. Вызывающая сторона может передать ей локальную переменную или указатель (* ptr). Вызываемая функция может копировать или не копировать данные из переданного объекта.

Этот вопрос является продолжением моего предыдущего вопроса , касающегося разработки C ++ Bada.

Ответы [ 4 ]

6 голосов
/ 28 сентября 2011

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

Кроме того, в качестве общего руководства, избегайте указателей и освобождайте память. C ++ разработан с учетом стековых объектов. Если нет веских причин использовать что-то другое, не делайте этого. new следует использовать в вашем коде только очень редко, а delete следует никогда никогда не использовать, то есть всегда разрешать обработку выделенной памяти автоматически (интеллектуальные указатели).

1 голос
/ 28 сентября 2011

Способ создания объекта зависит от того, что вы собираетесь делать.

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

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

Общая библиотека, такая как STL, разрешит оба объекта.

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

0 голосов
/ 28 сентября 2011

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

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

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

Список литературы должен быть очевидным. Вам нужно переместить одну и ту же память в разные места программы? Нужно ли нескольким вещам получать доступ к ТОЧНОЙ части памяти, а не только к копии?

Последнее, перформанс. Приведет ли использование кучи памяти к производительности? Указатели медленнее из-за дополнительной потребности во времени выделения. Им также требуется немного дополнительной памяти для хранения самого указателя (на самом деле незначительно, но вы все равно могли бы рассмотреть его в любом случае. Действительно зависит от вашего приложения).

0 голосов
/ 28 сентября 2011

Нет такой вещи как "простой объект".Объект - это объект - это объект.

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

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

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

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

Если вы будете следовать этим идеям методично, вы обнаружите, что вы очень редко будете создавать динамические объекты самостоятельнои, если вы это сделаете, то есть одна строка кода, которая имеет отношение (это дает вам «локальность»);например, auto p = std::make_shared<T>(a,b,c); или std::unique_ptr<T> p(new T(a,b,c));.Простой grep для new для всего вашего исходного кода может легко проверить, все ли ваши динамические выделения обрабатываются ответственно.

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