QSharedPointer, как их передавать и нужны ли они мне? - PullRequest
4 голосов
/ 23 марта 2012

Уже несколько дней пытаюсь понять общий указатель, и мне кажется, что я не могу его получить. Не уверен, очевидно ли это или слишком сложно. Прежде всего, кто-нибудь может дать мне пример, где бы вы НАСТОЯТЕЛЬНО использовали общие указатели. Примеры в Википедии для меня не имеют смысла. И как бы вы передали общий указатель на другую функцию или создать объект с общим указателем. Итак, как вы передаете это и где бы вы использовали это? ЛЮБАЯ информация или примеры были бы отличными.

Кроме того, у меня есть проблема, когда я не знаю, что использовать. У меня есть эта функция, где я выделяю QFile и передаю ее функции в другом классе. Эта функция принимает файл как QIODevice*, а затем создает объект, содержащий файл. Мне было интересно, что будет лучшим решением здесь и как (если я должен) использовать общий указатель здесь? Как я могу сделать общий указатель с <QFile> и передать его туда, где функция принимает <QIODevice>. Такое ощущение, что я вообще не получаю общих указателей ...

Мой другой подход состоял бы в том, чтобы поместить QFile в QScopedPointer. Затем я передаю его классу и при создании объекта, в котором будет храниться файл, использую QPointer или QScopedPointer. В конце первой вызывающей функции я должен вызвать take (), верно?

function () {
   QScopedPointer<QFile> item(new QFile("filename"));
   SomeClassObject->doStuff(item.data());
   item.take();
}
---------------------------------
SomeClass::doStuff(QIODevice *item) {
    _currentObject = new MyObject(item); // should _currentObject be a smartpointer?
    ...
}
---------------------------------
class MyObject {
    QPointer<QIODevice> _item;

    ...
    MyObject(QIODevice *item) {  _item = item; }
}

Итак, я хочу, чтобы хранить указатели и обрабатывать их во время создания, если «new» выдает исключение.

1 Ответ

8 голосов
/ 23 марта 2012

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

Что касается вашего кода, SomeClass::doStuff() должен иметь параметр QScopedPointer<QFile> (вместо QIODevice*), когда вы передаете ему item, который имеет этот тип.

То же самое с конструктором MyObject: он принимает параметр типа QPointer<QIODevice> или QSharedPointer<QIODevice>.В общем, везде, где вы будете использовать указатели, используйте QSharedPointer (с соответствующим типом шаблона).Это избавит вас от головной боли, связанной с последующим доступом к удаленным объектам.

Конечно, иногда вам действительно нужен необработанный указатель QIODevice (например, для вызова сторонней библиотеки), тогда вы будете использовать data() функция-член объекта общего указателя.Просто убедитесь, что вы не сохраняете (то есть сохраняете или иным образом копируете то, что необходимо) возвращенный необработанный указатель, потому что это подорвет назначение общих указателей - общие указатели не будут знать о вашем дополнительном необработанном указателе, который не находится подуправление объектами общего указателя.

EDIT: take() освобождает владельца указанного объекта от указателя в области, поэтому при уничтожении указателя в области он не удаляет объект.Вы не могли бы использовать его в ситуации, когда вы передали право собственности на что-то другое - как в вашем случае на MyObject.

...