Здравствуйте, AlexGin, Вы писали:
AG>Первый вариант — выглядит вполне корректно и логично (как для C++, так и для Qt).
сейчас для передачи владения в С++ семантика перемещения и только она выглядит логично. А когда вы передаёте голый указатель, то не можете гарантировать, что будет происходить дальше. Не, конечно можно лазить по документациям, но это мартышкин труд.
Это похоже на спор с чистым С. Ты им говоришь, что передавать указатель в С++ идеологически неверно, а они не понимают. Это как же, деды передавали и мы будем.
Здравствуйте, sergii.p, Вы писали:
SP>Это похоже на спор с чистым С. Ты им говоришь, что передавать указатель в С++ идеологически неверно, а они не понимают. Это как же, деды передавали и мы будем.
передавать голый невладеющий указатель вполне нормально
Здравствуйте, sergii.p, Вы писали:
SP>Здравствуйте, AlexGin, Вы писали:
AG>>Первый вариант — выглядит вполне корректно и логично (как для C++, так и для Qt).
SP>сейчас для передачи владения в С++ семантика перемещения и только она выглядит логично.
Но это зависит от задачи.
Например: зачем мне перемещать объект, если он нужен именно эдесь?
Вот пример:
m_pMainWidget = new MainWidget(this);
m_pVBoxLayout->addWidget(m_pMainWidget);
...
m_pMainWidget->setGeometry(...);
SP>А когда вы передаёте голый указатель, то не можете гарантировать, что будет происходить дальше.
Гарантировать, что будет дальше — ни в каком случае не возможно. Даже, если кажется, что от всех ошибок защитился!
SP>Не, конечно можно лазить по документациям, но это мартышкин труд.
Не понял, к чему Вы относите данную фразу?
SP>Это похоже на спор с чистым С. Ты им говоришь, что передавать указатель в С++ идеологически неверно, а они не понимают. Это как же, деды передавали и мы будем.
Идеология — это другое.
Ну передавай ссылку, а не указатель.
Однако, не везде это прокатит: нулевой ссылки, в отличие от Java и .NET, в C++ быть не может.
Здравствуйте, AlexGin, Вы писали:
AG>Но это зависит от задачи. AG>Например: зачем мне перемещать объект, если он нужен именно эдесь?
потому что вы отдали владение Компонент может запросто грохнуть ваш объект или скопировать в другую область памяти. У вас же не возникает вопросов почему здесь UB
std::vector<int> v = {0, 1, 42};
auto& front = v.front();
v.push_back(43);
std::cout << front;
Rust ваш код тоже не пропустит дальше. Это базовая проверка валидности кода. Если она провалена, то можно придумать кучу случаев когда код сломается.
Опять же в Java всё ок. Вот почему у меня и претензии к Qt. Он ласково шепчет, что можешь обо всём забыть и работать как в Java. Но по факту ты по-прежнему в С++. А тут такое беззаботное отношение к владению недопустимо.
AG>Гарантировать, что будет дальше — ни в каком случае не возможно. Даже, если кажется, что от всех ошибок защитился!
можно конечно, если придерживаться простых правил. Core guidline не просто так придумывали. Одно из таких правил — не использовать голые указатели.
SP>>Не, конечно можно лазить по документациям, но это мартышкин труд. AG>Не понял, к чему Вы относите данную фразу?
имел в виду, что эту работу можно было не делать, если бы фукнция была спроектирована как-то так
void addWidget(std::unique_ptr<Widget> w);
Здесь не нужна документация чтобы понять, что владение теряется. Сигнатура фукнции должна сама документировать, что происходит внутри.
AG>Ну передавай ссылку, а не указатель. AG>Однако, не везде это прокатит: нулевой ссылки, в отличие от Java и .NET, в C++ быть не может.
Здравствуйте, AlexGin, Вы писали:
AG>Здравствуйте, night beast, Вы писали:
NB>>Здравствуйте, AlexGin, Вы писали:
SaZ>>>>Второй случай — вы создали объект на стеке, поместили в лэйаут, и тут же удалили при выходе из скоупа (функции). Тоже всё корректно. AG>>>Какой смысл действий в этом случае? AG>>>Мёртвый указатель в лейоуте...
NB>>уберется при вызове деструктора l AG>Да, но время жизни этого объекта l ограничено функцией: addLabelToLayout — после выхода из этой функции: объект разрушен; указатель адресует мусор
Какой указатель? Какой мусор? Объект будет удалён сразу по выходу из функции. Если в Qt удаляется дочерний объект, то он всегда оповещает об этом родителя. Тут не важно как он был создан, в куче или на стеке.
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, SaZ, Вы писали:
SaZ>>То что в stl есть только unique/shared вовсе не значит что нельзя использовать другие парадигмы. Лично мне для GUI очень нравится подход — создал, указал куда всунуть (парент), забыл. И всё само работает.
NB>безотносительно Qt мне нравится принцип питона: "явное лучше, чем неявное" NB>то есть я смотря только на код должен не влезая во внутреннее устройство понимать, что происходит с владением объекта
Всегда надо понимать что вы делаете. Вам концепцию шаред поинтеров тоже же пришлось изучать — как минимум прочитать доку и понять что такое счётчик ссылок. Так же и в кутэ, один раз читаем доку про их модель владения, понимаем что вместо счётчика ссылок тут надо указать экземпляр родитель и всё, дальше всё явно. Объект живёт, пока мы его не удалим или пока не удалим его родителя.
Здравствуйте, SaZ, Вы писали:
NB>>безотносительно Qt мне нравится принцип питона: "явное лучше, чем неявное" NB>>то есть я смотря только на код должен не влезая во внутреннее устройство понимать, что происходит с владением объекта
SaZ>Всегда надо понимать что вы делаете. Вам концепцию шаред поинтеров тоже же пришлось изучать — как минимум прочитать доку и понять что такое счётчик ссылок.
ты не понял основной мысли.
речь не о концепциях, а о когнитивной нагрузке, испытываемой при чтении произвольного фрагмента пользовательского кода
есть две функции:
void add(Object* a);
void add(own<Object*> a);
обе функции делают одно и то же (забирают владение у вызывающего кода)
только во втором случае ты об этом знаешь, а в первом тебе нужно представлять какие процессы происходят в add
SaZ>Так же и в кутэ, один раз читаем доку про их модель владения, понимаем что вместо счётчика ссылок тут надо указать экземпляр родитель и всё, дальше всё явно. Объект живёт, пока мы его не удалим или пока не удалим его родителя.
проблема в том, что ты нифига не знаешь, захватывает addWidget владение, или нет
Здравствуйте, Shmj, Вы писали:
S>Вот, в QT QObject имеет свою парадигму управления памятью, без использования вумных указателей. Правильно ли это с вашей точки зрения?
Как минимум опасность есть от функций, которые принимают несколько голых владеющих указателей.
doSomething(new QLabel("1"), new QLabel("2"));
Если new выбросит bad_alloc или один из конструкторов, то есть вероятность возникновения утечки.
Конкретно, если исключение будет выкинуто вторым по порядку вызова new, то результат первого new утечет.
Какой new будет вычисляться первым, а какой вторым — по стандарту нет гарантии на порядок вычисления аргументов функции.
Здравствуйте, night beast, Вы писали:
NB>... NB>проблема в том, что ты нифига не знаешь, захватывает addWidget владение, или нет
Можно, пожалуйста, пример, где в кутэ не захватывается владение?
Мой основной посыл в том, что местами это непривычно (впрочем есть и определённый оверхед), но плюсы такого подхода разительно перевешивают минусы. В контексте программирования на этом фреймворке, разумеется.
Здравствуйте, sergii.p, Вы писали:
SP>потому что вы отдали владение Компонент может запросто грохнуть ваш объект или скопировать в другую область памяти.
Это аргументация уровня: "shared_ptr может не удалить объект". Навреное, в теории может, если это какой-то сильно кривой shared_ptr.
В Qt стандартный паттерн: дети живут пока родители живут. Понять проще, чем shared_ptr.
Здравствуйте, SaZ, Вы писали:
NB>>проблема в том, что ты нифига не знаешь, захватывает addWidget владение, или нет
SaZ>Можно, пожалуйста, пример, где в кутэ не захватывается владение?
да не проблема
открой хидеры и смотри функции, которые принимают указатели. по названию пытайся понять, захватывают или нет
например:
void QWidget::stackUnder(QWidget* w);
SaZ>Мой основной посыл в том, что местами это непривычно (впрочем есть и определённый оверхед), но плюсы такого подхода разительно перевешивают минусы. В контексте программирования на этом фреймворке, разумеется.
мой основной посыл не в плюсах или в минусах кютешного подхода (я об этом явно указал в сообщении
), а в том что код должен быть понятен без дополнительного знания контекста
Вот в том и основная проблема стиля с голыми указателями, не понятно, когда функция забирает владение, а когда — нет.
Например, в MFC также была куча функций с голыми указателями (CWnd::SetParent(CWnd*)), но не припомню чтобы там забиралось владение.
Т.е. стиль кодирования, когда голый указатель (возможно с const) выполняет роль опциональной ссылки с поддержкой значения nullptr, но никогда не отвечает за владение — это норм имхо.
Здравствуйте, qaz77, Вы писали:
Q>Здравствуйте, Shmj, Вы писали:
S>>Вот, в QT QObject имеет свою парадигму управления памятью, без использования вумных указателей. Правильно ли это с вашей точки зрения?
Q>Как минимум опасность есть от функций, которые принимают несколько голых владеющих указателей.
Q>
Q>doSomething(new QLabel("1"), new QLabel("2"));
Q>
doSomething(new QLabel(this, "1"), new QLabel(this, "2"));
Так утечки не будет.
Все Qt объекты умеют получать родителя первым аргументом, именно для решения этой проблемы.
Здравствуйте, Shmj, Вы писали:
S>Вот, в QT QObject имеет свою парадигму управления памятью, без использования вумных указателей. Правильно ли это с вашей точки зрения?
- Гиви, ты памыдоры лубиш?
— Есть лублу, а так — нэт!
Здравствуйте, so5team, Вы писали:
A>>Там же выше есть примеры, в т.ч. QString. Посмотри на него. Через него ты можешь сделать со строкой всё, что тебе надо. Как, собственно, во всех удобных стандартных библиотеках. На этом фоне каким надо быть архитектурным астронавтом, чтобы включать в стандартную библиотеку класс, который нужен ТОЛЬКО для стандартизации.
S>Если вы проведете опрос среди большого количества C++ разработчиков о том, хотят ли они видеть в стандартной библиотеке C++ один большой класс для работы со строками по типу QString, то вы удивитесь тому, насколько много скажет "нет".