Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/55: Рейтинг темы: голосов - 55, средняя оценка - 5.00
 Аватар для Tyson Fury
2 / 2 / 2
Регистрация: 23.10.2016
Сообщений: 139

Умные указатели в классах

15.02.2017, 00:58. Показов 10616. Ответов 12

Студворк — интернет-сервис помощи студентам
Допустим у меня есть класс:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
 
 
private:
    Ui::MainWindow *ui;
 
    QGraphicsScene *scene;
    IAlgorithm * m_pAlgorithm;
 
};
В нем есть поля-указатели:
C++ (Qt)
1
2
    QGraphicsScene *scene;
    IAlgorithm * m_pAlgorithm;
Данные указатели освобождают память в деструкторах.
Выделяется память для них путем вызова new.

Но я так понимаю, что это плохая практика и вместо new/delete нужно использовать умный указатель (например: QSharedPointer).

Значит, поля нужно прописывать вот так:
C++ (Qt)
1
2
    QSharedPointer<QGraphicsScene> shScene;
    QSharedPointer<IAlgorithm> shAlgo;
1. как же правильно конструировать класс, через умный указатель или просто указатель?
2. В Qt можно использовать свои умные указатели (QSharedPointer), а можно использовать стандартные (shared_ptr).
Какими лучше пользоваться?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.02.2017, 00:58
Ответы с готовыми решениями:

Умные указатели в Qt
Нужно создать список умных указателей на объекты типа QFile, которые будут автоматически удаляться при уничтожении указателя. Можете...

Умные указатели на QObject
Бывают ли случаи, когда имеет смысл использовать умные указатели на объекты-наследники QObject?

Умные указатели
Привет. Что-то разобраться до конца не могу, тк умных указателей не так то мало оказывается. Мне интересно, если я выделяю память под...

12
 Аватар для Горбаг
184 / 176 / 57
Регистрация: 25.09.2014
Сообщений: 834
15.02.2017, 10:00
Пользуйся каким хочешь. Я принципиально не пользуюсь умными указателями, чтобы не городить лишние сложночитаемые (для меня, имхо) громадины аля QSharedPointer<QGraphicsScene>.
Создание переменных через new - нормальная практика. Под ковром у QSharedPointer, насколько я знаю, все равно происходит все тоже самое. Просто тебе не нужно явно создавать и удалять содержимое своего указателя через:
C++ (Qt)
1
2
3
4
QGraphicsScene *scene = new QGraphicsScene();
...
delete scene;
scene = 0;
1
93 / 93 / 33
Регистрация: 17.03.2012
Сообщений: 536
15.02.2017, 10:11
Цитата Сообщение от Горбаг Посмотреть сообщение
Просто тебе не нужно явно создавать и удалять содержимое своего указателя через
Это преимущество умных указателей несколько глубже
Фишка их использования, например, в возврате указателя из функции и ситуация, когда код будет изменяться и изменяющий забудет освободить память, а если возвращать умный указатель, то память освободиться
Единственное, надо правильно определиться с типом умного указателя
Если вам не нравятся кутишные умные указатели, можете пользоваться из стандартной библиотеки, там буковок поменьше, все в нижнем регистре
1
Pied Piper
 Аватар для ArmanPrestige
237 / 228 / 57
Регистрация: 15.01.2013
Сообщений: 855
15.02.2017, 11:22
При конструировании гуя на самом деле нет необходимости в использовании QSharedPointer. Грубо говоря, кнопку мы добавили в диалог - при вызове деструктора диалога вызовется и деструктор кнопки. Полезнее может быть использование QPointer. Во всех остальных случаях я бы рекомендовал использование умных указателей, почитайте про RAII.

Добавлено через 1 минуту
Цитата Сообщение от Tyson Fury Посмотреть сообщение
В Qt можно использовать свои умные указатели (QSharedPointer), а можно использовать стандартные (shared_ptr).
Пользуетесь Qt - используйте его по максимуму. Если чего-то нету - только тогда я бы обращался к стандартной библиотеке.
1
93 / 93 / 33
Регистрация: 17.03.2012
Сообщений: 536
15.02.2017, 11:34
Цитата Сообщение от ArmanPrestige Посмотреть сообщение
Грубо говоря, кнопку мы добавили в диалог - при вызове деструктора диалога вызовется и деструктор кнопки.
Да нифига, если я динамически создаю объект кнопка, но не указываю ему родителем текущий виджет, память не освободиться при вызове деструктора этого виджета
Цитата Сообщение от ArmanPrestige Посмотреть сообщение
Пользуетесь Qt - используйте его по максимуму
С этим согласен, даже обеими руками за, не нужно изобретать многие велосипеды, которые уже есть и весьма удобны
1
 Аватар для Wyn
1073 / 654 / 230
Регистрация: 14.01.2016
Сообщений: 2,031
Записей в блоге: 9
15.02.2017, 11:44
Цитата Сообщение от Slip. Посмотреть сообщение
Да нифига, если я динамически создаю объект кнопка, но не указываю ему родителем текущий виджет, память не освободиться при вызове деструктора этого виджета
Это будет так, только если вы эту кнопку нигде не разместили. Если вы её где-то разместили, то в качестве parent будет автоматически выставлен следующий по старшинству QWidget.
1
93 / 93 / 33
Регистрация: 17.03.2012
Сообщений: 536
15.02.2017, 12:05
Wyn, Ну если в лэйаут какой-то, принадлежащий этому виджету добавили, то да
1
Pied Piper
 Аватар для ArmanPrestige
237 / 228 / 57
Регистрация: 15.01.2013
Сообщений: 855
15.02.2017, 12:21
Slip., ну обычно виджеты создаются, чтобы их отображать. Если ему не установили явно родителя или не добавили в лэйаут - то это ошибка разработчика. Поэтому, я взял за правило при создании виджета всегда передавать в конструктор родителя.
1
 Аватар для Tyson Fury
2 / 2 / 2
Регистрация: 23.10.2016
Сообщений: 139
16.02.2017, 01:34  [ТС]
О пользе умных указателей в с++ (в методах и т.д.) я в курсе.
Меня интересует конкретно поля класса, стоит ли там их использовать?

Добавлено через 7 часов 47 минут

Не по теме:

Ну ребята, вы меня расстроили)

0
 Аватар для icpu
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
16.02.2017, 10:06
Tyson Fury, тут не нужно вообще запариваться с указателями. Наследники от QObject - просто определите parent правильно, без циклов - и будет вам счастье.
Shared pointer сделан не для удобного хранения алгоритма, а для совладения объектом, когда, например, множество сущностей, создаваемое пользователем, делят одну модель. То же про unique pointer, только на 180 градусов.
Если часто удаляете-создаёте объект и есть проверки, делайте QPointer, он автоматически обнуляется при удалении объекта, меньше шансов на косяк. В противном случае оставляйте сырые указатели. Это, в конце концов, C++, а не хипстерское говно с решетками.
1
16.02.2017, 11:26

Не по теме:

Цитата Сообщение от icpu Посмотреть сообщение
Это, в конце концов, C++, а не хипстерское говно с решетками.
Однозначно лайк.

0
 Аватар для Tyson Fury
2 / 2 / 2
Регистрация: 23.10.2016
Сообщений: 139
16.02.2017, 17:22  [ТС]
Цитата Сообщение от icpu Посмотреть сообщение
Tyson Fury, тут не нужно вообще запариваться с указателями. Наследники от QObject - просто определите parent правильно, без циклов - и будет вам счастье.
А если это указатели на данные? Вот так например:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <QString>
#include <QMultiMap>
#include <QSharedPointer>
 
 
class A
{
    struct Node{
        QSharedPointer<Node> shLink_1;
        QSharedPointer<Node> shLink_2;
        QSharedPointer<Node> shLink_3;
        QSharedPointer<Node> shLink_4;
        QSharedPointer<Node> shParent;
        QVector<int> nodeState;
        int nodeCost;
        int distance;
        int indexEmpty;
 
        Node() : shLink_1(nullptr), shLink_2(nullptr), shLink_3(nullptr), shLink_4(nullptr), shParent(nullptr){}
    };
 
    QSharedPointer<Node> m_shRoot;
    QMultiMap<int, QSharedPointer<Node>> m_MultiMapOpen;
    QList<QSharedPointer<Node>> m_ListClose;
    QList<QVector<int>> m_ListResult;
 
public:
    explicit A();
    bool solvePuzzle();
    QList<QVector<int>> getSolution(int &moves);
 
private:
    bool checkNewNode(const QSharedPointer<Node> &shCurNode);
};
Адекватно вот так прописывать класс?
0
 Аватар для icpu
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
17.02.2017, 06:43
Сферически в вакууме? Вполне. Но я бы, к примеру, активнее использовал QWeakPointer там, где это имеет смысл, а именно, в тех случаях, когда мы не захватываем очередную ноду во владение. Ну и дважды подумал, а мне правда нужно отдавать управление памятью на откуп системе, или я и сам сусам.

З.Ы. explicit A(); explicit здесь лишний, он предотвращает неявное обращение параметра конструктора при записи в виде приравнивания aka
C++
1
2
3
4
5
6
7
struct A{
  explicit A(int i){}
  A(char i){}
}; 
 
A a = 1; // ERROR
A a = ' '; // OK
в остальных случаях он бесполезен.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.02.2017, 06:43
Помогаю со студенческими работами здесь

Умные указатели
Пишу класс дерево поиска:template&lt;typename T, typename Compare&gt; class AvlTree { private: struct Node { T...

умные указатели
у меня например есть куча юнитов, у каждого из них есть указатель на игровой ресурс (допустим камень). Есть такая задумка: когда камень...

Умные указатели
Здравствуйте! вопрос указатель auto_ptr почитала литературу, там написано он считывает и удаляет ссылки, т.е. он получает какие-то...

Умные указатели
#include &lt;fstream&gt; #include &lt;algorithm&gt; #include &lt;vector&gt; #include &lt;iostream&gt; #include &lt;memory&gt; using namespace std; ...

Умные указатели
Насколько я понял для того что бы предотвратить передачу права владения используют const. Код из примера: template &lt;class T&gt; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! в-строка - входное арифметическое выражение в инфиксной(обычной). . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru