2016-09-04 4 views
1

Я пытаюсь получить управляемый объект сглаженного общего указателя. Моя идея заключалась в использовании слабого указателя. Так как слабые указатели не дают никаких объектов, я думал, что создание слабого указателя из общего указателя заставит слабый указатель забыть сохраненный объект сглаженного общего указателя и, следовательно, блокировка слабого указателя даст общий указатель с равным сохраненным и управляемым указатели. Но результаты меня смутили. Помнит ли слабый указатель, из какого указателя общего доступа? И есть ли способ получить управляемый объект сглаженного общего указателя?Неожиданное поведение интеллектуальных указателей

template<class T> struct Deleter { 
    void operator()(T* p) const {}; 
}; 

Deleter<T> d {}; 
T t1 {}; 
T* p1 = &t1; 
T t2 {}; 
T* p2 = &t2; 
auto sp1 = std::shared_ptr<T>(p1,d); 
auto sp2 = std::shared_ptr<T>(sp1,p2); 
auto wp = std::weak_ptr<T>(sp2); 
std::cout << sp1.get() << " " << sp2.get() << " " << wp.lock().get() << std::endl; 

продукции 0x7fff5798c958 0x7fff5798c948 0x7fff5798c948

+3

В чем вопрос? Какой другой результат вы ожидали? – Barry

+0

Я ожидал '0x7fff5798c958 0x7fff5798c948 0x7fff5798c958' –

+0

Было бы очень плохо, если бы' shared_ptr' и 'weak_ptr' действовали так, как вы ожидали. Алиасирование 'shared_ptr' не будет столь же полезным. – StoryTeller

ответ

1

Помнит ли слабый указатель от того, что доля указатель строится?

Он запоминает необработанный указатель, который был сохранен shared_ptr, из которого он был построен. Я думаю, что было бы очень сложно, если бы все работало так, как вы ожидаете. Например, если функция получила shared_ptr<T> в качестве аргумента, она понятия не имеет, является ли она псевдонимом или нет. И если эта функция захотела взять weak_ptr из этого shared_ptr, было бы, я думаю, очень удивительным поведением, чтобы найти, что актуализация того, что weak_ptr - shared_ptr, дает совершенно другой объект, кроме исходного shared_ptr, из которого он был получен.

Также обратите внимание, что псевдоним shared_ptr может хранить другой тип, отличный от shared_ptr, который является псевдонимом. Эти типы даже не должны быть конвертированы в/из друг друга. И weak_ptr, который построен на основе псевдонимов shared_ptr, получает свой сохраненный тип из shared_ptr, который был построен из (или неявно конвертируемого типа).

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

И есть ли способ получить управляемый объект с псевдонимом общего указателя?

Насколько я знаю, нет. Возможно, должно быть. Если вы считаете, что эта функция будет полезна, предложите ее. https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-proposals

+0

Спасибо за объяснение. Сценарий, который я представил, был создан, чтобы обмануть сглаженный общий указатель, чтобы получить свой управляемый объект. Я был просто удивлен, что ему не хватает этой функциональности. Но для этого могут быть веские причины. –

+0

@ JiříLechner: Я подозреваю, что единственная причина, по которой ему не хватает этой функциональности, - это просто, что никто не думал об этом. И я подозреваю, что никто не думал об этом, потому что никто не нуждался в нем. Если вам это нужно, отформатируйте свой вариант использования и сделайте сообщение на форуме, на котором я связан, в нижней части моего ответа. –

Смежные вопросы