Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

использование QSharedPointer (аналог shared_ptr в Qt)

13K
14 января 2015 года
Jawello
11 / / 11.04.2008
Доброе время суток.

Возник следующий вопрос:


 
Код:
QSharedPointer<int> ptr1 = QSharedPointer(new int (12));
QSharedPointer<int> ptr2 = ptr1;
QSharedPointer<int> ptr3 = QSharedPointer(ptr1.data());
QSharedPointer - аналог в Qt для std::shared_ptr.
Метод data возвращает обычный указатель (int*).

Получается, что ptr1 и ptr2 указывают на одну область памяти, счетчик ссылок равен 2. Но что произойдет после 3 строчки? По идее ptr3 так же должен указывать на ту же область памяти, что ptr1 и ptr2. Но не совсем понятно увеличится ли счетчик ссылок на данную область памяти?!

спасибо за ответы.
326
14 января 2015 года
sadovoya
757 / / 19.11.2005
По-моему (лучше в доках посмотрите) нельзя создавать новые шареды на базе одного и того-же сырого. Т.е. третья строчка не верна.
13K
14 января 2015 года
Jawello
11 / / 11.04.2008
Цитата: sadovoya
По-моему (лучше в доках посмотрите) нельзя создавать новые шареды на базе одного и того-же сырого. Т.е. третья строчка не верна.

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

T * QSharedPointer::data () const

Returns the value of the pointer referenced by this object.

Note: do not delete the pointer returned by this function or pass it to another function that could delete it, including creating QSharedPointer or QWeakPointer objects.

326
18 января 2015 года
sadovoya
757 / / 19.11.2005
Меня еще вначале напрягло такое создание статического объекта:

 
Код:
QSharedPointer<int> ptr1 = QSharedPointer(new int (12));
(кстати, не все компиляторы смогут вывести сами опущенный параметр шаблона. Лучше так:

 
Код:
QSharedPointer<int> ptr1 = QSharedPointer<int>(new int (12));
)
Я бы написал классически:

 
Код:
QSharedPointer<int> ptr1(new int (12));
Потом я нашел в примерах на те-же шареды в доках Qt спокойное использование первой формы (но с указанием параметра шаблона разумеется). Могу предположить, что Qt достаточно умна, чтобы сама оптимизировать создание объекта из временного безымянного (т.е. реально не создавать безымянный шаред-поинтер как промежуточный или семантику move использует). С другой стороны, возможно в Qt расходы на создание промежуточных шаред-поинтеров не существенны, если последние не слишком громоздки. Но сколько в счетчике ссылок тут тогда будет сказать трудно - 2 или 1? Если временного объекта нет или он сразу уничтожается, то 1. В противном случае - 2.
Но, нам это все-равно, если посмотреть практически. Qt сама следит за счетчиком и по достижению числа ссылок 0 уничтожает объект, обслуживаемый шаредным указателем.

По поводу изначального вопроса могу добавить еще следующее.
Добавление такого макроса

 
Код:
#define QT_SHAREDPOINTER_TRACK_POINTERS
до включения шаредных указателей позволяет сгенерить ошибку в случае вашей неверной третьей строчки. Удобно для обнаружения подобных ошибок. Нашел в той-же справке.
326
18 января 2015 года
sadovoya
757 / / 19.11.2005
Поскольку момент важный, учитывая энтузиазм перехода к новому стилю в духе move-семантики С++11/14, хочу пояснить. Речь скорее не о Qt, а о С++ вообще.
Если бы дело касалось только стандарта C++11 и 14, подобная форма записи не особо смутила:

 
Код:
SomeClass a = SomeClass(something);
Можно предположить, что тут используется move-конструктор. Да и тут есть одно "но" - если он задан или автоматически сгенерирован (автоматически не всегда бывает, см. тут).
Если даже не так, то и тут не все плохо. Многие компиляторы и до нового стандарта научились Return Value Optimization и подобному в духе move-семантики. Поэтому для них тоже все будет почти без накладных расходов. Чтобы не выяснять наличие move-конструктора или уповать на разумность компилятора, лучше создавать объект прямо:

 
Код:
SomeClass a(something);
Да и в любом случае, хоть move почти ничего не стоит в сравнении с copy, зачем лишние затраты. А в данном примере прямое создание даже синтаксически короче.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог