Ручное владение объектами против умных указателей - PullRequest
4 голосов
/ 17 декабря 2010

Прямо сейчас, владение / удаление объекта в моем проекте C ++ отслеживается вручную (в основном с помощью комментариев).Почти каждый объект, выделенный для кучи, создается с использованием фабрики сортов

например,

auto b = a->createInstanceOfB(); //a owns b
auto c = b->createInstanceOfC(); //b owns c
//auto k = new K(); //not in the code
...
//b is no longer used..
a->destroyInstanceOfB(b); //destroyInstanceOf calls delete on it

Какие преимущества, если таковые имеются, обеспечат интеллектуальные указатели в этой ситуации?

Ответы [ 3 ]

9 голосов
/ 17 декабря 2010

Вы должны беспокоиться не о создании, а об удалении.

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

Тип «только для одного владельца» (std::auto_ptr) также освобождает вас от обязанности удаления, но разрешает использовать только одного владельца за раз (хотя право собственности может быть передано). Это полезно для объектов, которые вы передаете как указатели, но вы все равно хотите, чтобы они автоматически очищались, когда они выходят из области видимости (чтобы они хорошо работали в контейнерах, и развертывание стека в случае исключения работает, как и ожидалось).

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

2 голосов
/ 17 декабря 2010

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

В конечном счете, умные указатели уменьшают количество источников ошибок, и нет особых причин не использовать их.

1 голос
/ 17 декабря 2010

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

Трудный случай, когда вы разделяете право собственности. В этом случае вам понадобится smart-ptrs (или что-то еще) для автоматического определения, когда на самом деле удалять объект.

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

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