Начало работы с умными указателями в C ++ - PullRequest
6 голосов
/ 07 октября 2010

У меня есть приложение C ++, которое широко использует указатели для поддержки довольно сложных структур данных. Приложение выполняет математическое моделирование больших массивов данных (которые могут занимать несколько ГБ памяти) и компилируется с использованием Microsoft Visual Studio 2010.

Сейчас я перерабатываю важную часть приложения. Чтобы уменьшить количество ошибок (висячие указатели, утечки памяти и т. Д.), Я бы хотел начать использовать умные указатели. Жертва памяти или производительности приемлема, если она ограничена.

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

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

Как лучше всего начать внедрять умные указатели? Простая замена указателей [наугад] умными указателями не кажется правильным способом и, вероятно, не дает всех (или каких-либо из) преимуществ умных указателей. Но какой метод лучше?

Какие типы умных указателей мне следует дополнительно изучить? Иногда я использую std :: auto_ptr для освобождения локально выделенной памяти, но в C ++ 0x это, похоже, не используется. Является ли std :: unique_ptr лучшей альтернативой? Или я должен идти прямо к общим указателям или другим типам умных указателей?

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

Заранее спасибо за ваши идеи и предложения.

Ответы [ 2 ]

3 голосов
/ 07 октября 2010

Я рекомендую использовать unique_ptr, когда это возможно (это может потребовать некоторого анализа программы) и shared_ptr, когда это невозможно.В случае сомнений используйте shared_ptr для обеспечения максимальной безопасности: при передаче управления контейнеру счетчик ссылок просто перейдет к двум, а затем обратно к одному, и контейнер в итоге delete автоматически свяжет связанный объект.Когда производительность становится проблемой, рассмотрите возможность использования boost::intrusive_ptr.

1 голос
/ 07 октября 2010

Вот 3 сорта, найденные в новом стандарте C ++ 11 (unique_ptr заменяет auto_ptr)

http://www.stroustrup.com/C++11FAQ.html#std-unique_ptr

http://www.stroustrup.com/C++11FAQ.html#std-shared_ptr

http://www.stroustrup.com/C++11FAQ.html#std-weak_ptr

Вы можете прочитать текст для каждого указателя, и есть объяснение того, когда использовать какой там.Для управления локальной памятью Unique_ptr является выбором.Он не подлежит копированию, но может быть перемещен, так что когда вы перемещаете его, получатель становится его владельцем.

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

weak_ptr используется вместе с shared_ptr.Он позволяет «заблокировать», чтобы увидеть, существует ли ссылочный объект shared_ptr, прежде чем пытаться получить доступ к внутреннему объекту.

...