C++: Loki StrongPtr выглядит небезопасным для меня, это так?
В настоящее время я смотрю на наиболее популярные реализации интеллектуальных Ptr, такие как повышение общих и слабых указателей, а также указатель loki Smart и Strong, поскольку я хочу реализовать свой собственный и, насколько я понимаю, указатель 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 ответа
Что касается использования assert
, это ошибка программирования для использования operator->
на пустом месте StrongPtr<>
пример; то есть, вызывающий абонент обязан убедиться, что StrongPtr<>
экземпляр не пустой перед разыменованием его. Почему что-то большее, чем assert
быть нужным? Тем не менее, если вы считаете, что другое поведение более уместно, чем assert
тогда это именно то, для чего политика.
Это принципиальная разница между предусловиями и постусловиями; вот длинная, но очень хорошая тема по теме: comp.lang.C++.moderated: исключения. Прочитайте, в частности, посты Д. Абрахамса, поскольку он подробно объясняет, что я утверждаю как понятный факт.;-]
Что касается безопасности потока StrongPtr<>
Я подозреваю, что большая часть Loki предшествует любым серьезным проблемам с безопасностью потоков; с другой стороны, boost::shared_ptr<>
а также std::shared_ptr<>
явно гарантированно поточно-ориентированный, поэтому я уверен, что их реализации создают "лучшую" (хотя и более сложную) основу для изучения.
После прочтения, я думаю, что я видел обоснование.
StrongPtr
объекты являются двойственными в том смысле, что они представляют собой Strong
а также Weak
Рекомендации.
Механизм assert
отлично работает на Strong
версия. На Weak
версия, это ответственность вызывающего абонента, чтобы гарантировать, что указанный объект будет жить достаточно долго. Это может быть достигнуто либо:
- автоматически, если вы знаете, что у вас есть
Strong
версия - вручную, создав
Strong
пример
Преимущество по отношению к std::shared_ptr
является то, что вы можете избежать создания нового объекта, когда вы уже знаете, что этот элемент переживет ваше использование. Это спорно дизайнерское решение, но работает отлично подходит для специалистов (из которых Alexandrescu undoubtebly есть). Возможно, он не был нацелен на обычных пользователей (нас), для которых Strong
версия была бы принята намного лучше имхо.
Можно также утверждать, что всегда легче критиковать с точки зрения прошлого. Loki
При всем своем величии стар.