C ++: Loki StrongPtr выглядит небезопасно для меня, это так? - PullRequest
1 голос
/ 03 мая 2011

В настоящее время я смотрю на наиболее популярные реализации интеллектуальных Ptr, такие как повышение общих и слабых указателей, а также loki Умный и сильный указатель , поскольку я хочу реализовать свою собственную и, насколько я понимаю, выглядит указатель Loki Strongнебезопасно для меня, но я скорее думаю, что я понимаю это неправильно, поэтому я хотел бы обсудить, безопасно это или нет.Причина, по которой я думаю, что это небезопасно, заключается в том, что, насколько я могу судить, он не обрабатывает слабые указатели (то есть StrongPtr, где false указывает на его слабость) с достаточной тщательностью:

например функции разыменования:

PointerType operator -> ()
{
KP::OnDereference( GetPointer() ); //this only asserts by default as far as i know
//could be invalidated right here
return GetPointer();
}

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

Насколько я понимаю, вам придется либосоздайте экземпляр strongPtr для ptr, который вы разыменовываете, чтобы гарантировать, что он не станет недействительным на полпути.Я думаю, что это также причина, по которой boost не позволяет разыменовать слабый_птр без предварительного создания экземпляра shared_ptr.Я думаю, что Lokis StrongPtr Constructor страдает той же проблемой.

Это проблема или я неправильно читаю src?

Ответы [ 2 ]

3 голосов
/ 03 мая 2011

Что касается использования assert, то это ошибка программирования для использования operator-> в пустом StrongPtr<> экземпляре; то есть, вызывающий абонент несет ответственность за обеспечение того, чтобы экземпляр StrongPtr<> не был пустым перед разыменованием его. Зачем нужно что-то большее, чем assert? Тем не менее, если вы считаете какое-либо другое поведение более подходящим, чем assert, то это именно то, для чего предназначена политика.

Это фундаментальное различие между предусловиями и постусловиями; Вот длинная, но очень хорошая тема по теме: comp.lang.c ++. moderated: исключения . Прочитайте, в частности, посты Д. Абрахамса, поскольку он подробно объясняет, что я утверждаю как понятный факт. ; -]

Относительно безопасности потока StrongPtr<>, я подозреваю, что большинство Loki предшествовало любым серьезным проблемам безопасности потока; с другой стороны, boost::shared_ptr<> и std::shared_ptr<> явно гарантированно гарантируют поточнобезопасность, поэтому я уверен, что их реализации создают «лучшую» (хотя и гораздо более сложную) основу для изучения.

0 голосов
/ 03 мая 2011

После прочтения, я думаю, я нашел обоснование.

StrongPtr объекты двойственны в том смысле, что они представляют собой ссылки Strong и Weak.

Механизм assert прекрасно работает на Strong версии.В версии Weak вызывающая сторона отвечает за то, чтобы объект, на который ссылаются, проживал достаточно долго.Это может быть достигнуто либо:

  • автоматически, если вы знаете, что у вас есть Strong версия
  • вручную, создав Strong экземпляр

Преимущество по сравнению с std::shared_ptr заключается в том, что вы можете избежать создания нового объекта, если вы уже знаете, что этот предмет переживет ваше использование.Это спорно дизайнерское решение, но работает отлично подходит для специалистов (из которых Alexandrescu undoubtebly есть).Возможно, он не был нацелен на обычных пользователей (нас), для которых принудительное использование Strong версии было бы намного лучше imho.

Можно также утверждать, что всегда легче критиковать с пользойзадним числом.Loki, при всем своем величии, стар.

...