Russian Qt Forum
Ноябрь 25, 2024, 09:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Как лучше создавать объекты  (Прочитано 7038 раз)
zagruzkaaa
Гость
« : Август 27, 2015, 16:46 »

Создаю различные объекты на форме через код, например кнопки, тексредакторы и т.д. Они будут находится на форме с самого начала и до конца закрытия формы. Так вот: лучше создавать их через указатель, т.е через new или без? И в чем отличие? Спасибо
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #1 : Август 27, 2015, 17:07 »

Код:
без new объекты создаются на стеке и уничтожаются как только объект выходит из зоны видимости (стек убивается).
зона видимости ограничена фугурными скопками (да поправят меня строгие форумчане), это: функции, классы, циклы и т.п. вы можете просто создать фигурные скопки и туда код писать, не обязательно, чтобы они относились к какому-нибудь оператору / функции.

например, вы создали без new в функции и после того как функция выполнится, то все объекты в ней убиваются

[code=cpp]
void foo() {
    QWidget w;
    w.show();  // w живет и видим пока функция выполняется
}
Поэтому, например, если вы хотите создать функцию, в которой создаются окна, то нужно создавать их с new

А вот диалоги удобно создавать в стеке, потому что, когда вызываете функцию явно exec() или какой-нибудь их метод для их вызова (например, getOpenFileName у qfiledialog), то пока их окна открыты выполнение функции остановлено и уже после закрытия окна дальше пойдет выполнение (для одного потока).
Код
C++ (Qt)
void foo() {
...
   QDialog w;
   w.exec(); // пока диалог открыт, дальше этой строки не выполняется код
...
}

Если вы создаете объекты, которые нужны только при выполнении функции, то создаете без new

это лучше
Код
C++ (Qt)
void foo {
   QString s = "Hello";
   qDebug() << s;
}
 
чем это
Код
C++ (Qt)
void foo {
   QString * s = new QString("Hello");
   qDebug() << s;
   delete s;
}
[/code]
« Последнее редактирование: Август 27, 2015, 17:20 от gil9red » Записан

kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Август 27, 2015, 18:05 »

А если без new:

Код
C++ (Qt)
 
class Widget : public QWidget
{
...
private:
   QLabel m_label;
   QLineEdit m_lineEdit;
}
 
 

то что? Подмигивающий
Записан

ArchLinux x86_64 / Win10 64 bit
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #3 : Август 27, 2015, 21:13 »

А если без new:

Код
C++ (Qt)
 
class Widget : public QWidget
{
...
private:
   QLabel m_label;
   QLineEdit m_lineEdit;
}
 
 

то что? Подмигивающий

Было лень и конец рабочего дня, чтобы все варианты описывать Улыбающийся
Записан

zagruzkaaa
Гость
« Ответ #4 : Август 27, 2015, 22:37 »

как раз интересно, в случае описание объектов класса: их лучше создавать через указатель или без
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Август 28, 2015, 08:25 »

А если без new:

Код
C++ (Qt)
 
class Widget : public QWidget
{
...
private:
   QLabel m_label;
   QLineEdit m_lineEdit;
}
 
 

то что? Подмигивающий
Та ничего хорошего. В простом примере выше все будет работать, в более сложных нет, получите двойное удаление

как раз интересно, в случае описание объектов класса: их лучше создавать через указатель или без
Здесь однозначно указатель
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #6 : Август 28, 2015, 11:59 »

Та ничего хорошего. В простом примере выше все будет работать, в более сложных нет, получите двойное удаление
И примен такого случая сможете привести?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Август 28, 2015, 12:22 »

Цитата: cpp
class Widget : public QWidget
{
...
private:
    QWidget m_widget;
    QLabel m_label;
}
Пусть m_label должен иметь родителем m_widget. Тогда (при удалении Widget), если первым удалится m_label - все норм, он вычеркнется из чайлдов m_widget. Но если наоборот - тогда m_widget захочет грохнуть m_label, а это не указатель на кучу. Конечно если объявлять "в нужном порядке" - будет работать, но ну его нафиг
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #8 : Август 28, 2015, 12:26 »

Вам придется их описывать/конструировать в нужном порядке, иначе у вас даже не сконструируется.
Поэтому, это рабочий случай. Стандарт гарантирует порядок конструирования/разрушения, а компилятор предупредит о нарушении порядка.
« Последнее редактирование: Август 28, 2015, 12:30 от Old » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #9 : Август 28, 2015, 13:32 »

А что там про выравнивание в памяти? Без указателей вроде же лучше?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Август 28, 2015, 13:42 »

..., а компилятор предупредит о нарушении порядка.
Непонимающий
Код
C++ (Qt)
class CBad : public QWidget {
public:
CBad( void ) : m_lab("Lab", &m_widget)
{
}
 
public:
QLabel m_lab;
QWidget m_widget;
};
 
Не вижу даже варнинга  Улыбающийся

А что там про выравнивание в памяти? Без указателей вроде же лучше?
Адрес структур/классов выравнивается одинаково, не зависит от того где распределяется структура. "Парент удаляет чайлда" - а значит парент предполагает что чайлд в куче. Пытаться это как-то обходить не очень разумно, да и не видно зачем
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #11 : Август 28, 2015, 14:50 »

Не вижу даже варнинга  Улыбающийся
А программа работает?
Поэтому я и написал, что вам придется соблюдать порядок конструирования, иначе до двойного освобождения дело даже не дойдет.
« Последнее редактирование: Август 28, 2015, 14:55 от Old » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #12 : Август 28, 2015, 15:05 »

Не вижу даже варнинга  Улыбающийся
А программа работает?
Поэтому я и написал, что вам придется соблюдать порядок конструирования, иначе до двойного освобождения дело даже не дойдет.

А почему бы ей не работать? Он же ссылку берет, а она рабочая. Вот если бы он значение брал, то получил бы лажу.

Код
C++ (Qt)
struct A
{
int a;
int b;
A() : a(b), b(10) {std::cout << a << " " << b << std::endl;}
};
...........
./a.out
0 10
[/code!
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Август 28, 2015, 15:14 »

А почему бы ей не работать? Он же ссылку берет, а она рабочая. Вот если бы он значение брал, то получил бы лажу.
Не важно по ссылке или по значению. Объект label, получив ссылку, воспользуется методами  объекта widget, а он еще не сконструирован.
Поэтому, придется widget декларировать и конструировать первым, а если попробуете конструировать в другом порядке чем декларировали - получите предупреждение.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Август 28, 2015, 15:20 »

А почему бы ей не работать? Он же ссылку берет, а она рабочая. Вот если бы он значение брал, то получил бы лажу.
В данном случае она берет адрес члена, это само по себе корректно, но вызывается метод этого члена, а он-то еще не сконструирован - вылет. Ну и в конце-концов  можно было и так
Код:
class CBad2 : public QWidget {
public:
CBad2( void ) : m_lab("Lab")
{
          m_lab.setParent(&m_widget);
}
 
public:
QLabel m_lab;
QWidget m_widget;
};
Тоже полетит но не сразу. Поэтому всю затею "члены вместо указателей" надо признать совершенно никчемной, тем паче в разделе для новичков
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.181 секунд. Запросов: 23.