Как предотвратить удаление указателей, управляемых QSharedPointer - PullRequest
1 голос
/ 11 ноября 2010

У меня есть некоторые прерывистые ошибки сегментации в приложении Qt. Я думаю, что проблема связана с нашим (плохим) использованием QSharedPointer. Документация Qt гласит :

QSharedPointer :: QSharedPointer (T * ptr): Создает QSharedPointer, который указывает на ptr. Указатель ptr становится управляемым этим QSharedPointer, и не должен передаваться другому объекту QSharedPointer или , удаленному вне этого объекта .

Я думаю, что мы делаем оба не должны ...: /

Существует ли способ ООП, обеспечивающий невозможность удаления или передачи указателя, управляемого QSharedPointer, другому QSharedPointer?

Лучшим решением будет ошибка компилятора.

Ответы [ 4 ]

8 голосов
/ 11 ноября 2010

Обычный шаблон - поместить оператор new в конструктор умного указателя, например:

QSharedPointer<Obj> p (new Obj(2)); 

Таким образом, у вас никогда не будет ссылки на сам голый указатель.

Если вы реорганизуете свой код так, чтобы все новые операторы были в таких строках, все ваши проблемы будут решены.

1 голос
/ 11 ноября 2010

Я не знаком с конкретной реализацией общего указателя в Qt, но как общее руководство: попытка смешать необработанные указатели с управляемыми указателями обычно заканчивается кровью.Как только вы «доверяете» реализации совместно используемого указателя, вступая во владение вашими динамически распределяемыми данными, вы ни при каких обстоятельствах не должны пытаться самостоятельно управлять временем жизни объекта (например, удаляя предоставленный указатель).

Isесть ли ООП способ обеспечить невозможность удаления указателя, управляемого QSharedPointer?

Полагаю, вы могли бы представить некоторую странную технику, в которой у указанного типа был бы закрытый деструктор и объявить QSharedPointer как друга (которыйэффективно предотвращать компиляцию любого «внешнего удаления», но я бы не поспорил, что из этого может получиться что-то хорошее (и учтите, что это сделает ваш тип абсолютно непригодным для использования, если только new'ed и не переданы в QSharedPointer).

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

Я не могу думать ни о каком, и это еще одна причина, почему выследует избегать манипулирования необработанным указателем, как только этоправо собственности было передано QSharedPointer.

1 голос
/ 11 ноября 2010

Что ж, OOP-esque способ состоял бы в том, чтобы создать необработанный указатель как закрытый член в классе-оболочке и выполнять действия над указателем только через методы, которые воздействуют на совместно используемый указатель.хотя это глупо, не правда ли?

Или вы можете сделать свой класс с указателем raw базовым классом для других классов и сделать указатель raw личным членом в классе.В этом отношении вы более или менее создаете абстрактный класс, который ничего не делает.Вместо этого ваши производные классы должны выполнять всю работу, и, поскольку они не могут получить доступ к необработанному указателю, компиляция не удастся ... хотя это не остановит кого-то от простого копирования значения необработанного указателя из общего указателя.

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

Редактировать: Я мог бы добавить, что независимо от того, используете ли вы общие указатели, это звучит так, как будто вы являетесь владельцемпроблемы.Если указатель был создан в одной области, он должен быть удален в этой области, если только функция, которой он передан по контракту , не станет владельцем указателя.Использование общего указателя в этом сценарии в конечном итоге приведет только к различным ошибкам.Похоже, у вас проблемы с дизайном глубже, чем просто обмен указателями.

0 голосов
/ 12 ноября 2010

Проверьте ваш код на предмет использования .data () и убедитесь, что возвращаемые данные не сохранены и не удалены.Я не думаю, что жесткая ошибка компилятора была бы хороша, потому что иногда можно передать необработанный указатель, например, в функцию, которая не хранит и не удаляет переданные указатели.(Особенно при использовании стороннего кода вы не всегда можете изменить все, чтобы использовать общие указатели, и часто вы хотите, чтобы он работал как с необработанными, так и с общими ptrs).Можно отметить QSharedPointer :: data () как устаревший (путем установки исправления Qt), чтобы получить предупреждение о времени компиляции.

...