2017-01-27 17 views
2

Может кто-то объяснить просто причину, почему это не работает:общий указатель и сырой указатель жизни

std::shared_pointer<Bar> getSharedPointer() { 
    return std::make_shared<Bar>(); 
} 

... 

auto foo = getSharedPointer().get(); 

По-видимому, используя необработанный указатель foo вызовет Segfault, потому что срок службы совместно указатель, возвращаемый getSharedPointer() будет закончиться. Как бы то ни было, я ожидаю, что он продлится до конца его объема (как и любой блок внутри).

Это правильно и есть ли аналогичные примеры для этой ситуации?

+1

Не может найти 'getSharedPointer' описывался в стандартной библиотеке или общих третьих лицах. Не знаю, что произойдет. Порекомендуйте добавить немного больше информации. – user4581301

ответ

7

Для getSharedPointer().get();, getSharedPointer() возвращает временный std::shared_ptr, который будет немедленно уничтожен после выражения, и управляемый им указатель будет удален. После этого foo станет болтаться, любое разыменование на нем вызывает UB.

auto foo = getSharedPointer().get(); 
// foo have become dangled from here 

Вы можете использовать переменную с именем вместо:

auto spb = getSharedPointer(); 
auto foo = spb.get(); 
// It's fine to use foo now, but still need to note its lifetime 
// because spb will be destroyed when get out of its scope 
// and the pointer being managed will be deleted too 
+0

, пожалуйста, добавьте примечание о том, что 'spb' будет продолжаться только до конца области –

1
auto foo = getSharedPointer().get(); 

Всякий раз, когда функция возвращает тип, который не является ссылкой, то результат вызова функции является Rvalue. Кроме того, поскольку функция getSharedPointer() возвращает тип класса, результатом является временный объект.

Срок службы этого временного объекта определяется как окончание оценки самого внешнего выражения, здесь getSharedPointer().get(). Как только переменная foo инициализируется, интеллектуальный указатель владельца уничтожается; когда последний shared_ptr, владеющий этим объектом, уничтожается, объект удаляется.

Здесь getSharedPointer() всегда возвращает shared_ptr, что не разделяет управляемый объект (use_count() в 1), так что, когда эта копия последнего shared_ptr уничтожается объект уничтожается и указатель на объект является недействительным.

(я не знаю, почему вы возвращаете shared_ptr, а не unique_ptr здесь.)

Правильное использование интеллектуального указателя или любого класса, который «владеет» (контролирует срок службы) других ресурсов (ресурсы, которым вы по-прежнему разрешены напрямую), заключается в том, чтобы сохранить «умного» указателя/владельца в живых до тех пор, пока вам нужно получить доступ к ресурсу ressource.

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

std::shared_pointer<Bar> foo = getSharedPointer(); 
// use foo.get() 

Вы можете скрыть точный тип управляемого объекта:

std::shared_pointer<auto> foo = getSharedPointer(); 
+0

. Вам придется снова обратиться к коду, чтобы узнать, имеет ли смысл использовать уникальный ptr в приложении, но спасибо за то, что он поднял голову; Я проверю это. Кроме того, вы точно объяснили, что мне нужно знать о временных объектах и ​​сроках жизни, которые я не смог просветить из-за того, что я новичок с cpp. Благодарю. – tau