Почему мы не можем создать объект в Qt без ключевого слова new (т.е. в стеке)? - PullRequest
4 голосов
/ 05 сентября 2010

Почему мы не можем создать объект в QT без ключевого слова new? Обычно мы создаем указатель на объект, например так:

QLabel *ql=new QLabel();    ql->show()

Но я хочу создать такой объект:

QLabel ql=QLabel();    ql.show()

Возможно ли это?

Ответы [ 5 ]

20 голосов
/ 05 сентября 2010

Дело в том, что элементы управления Qt (метки, кнопки) находятся в иерархии (например, кнопки принадлежат формам).И способ реализации Qt требует, чтобы при уничтожении объекта все объекты, принадлежащие ему, также уничтожались.

Если вы помещаете объекты в стек (вот как «создать без new ключевое слово»на самом деле называется), они будут уничтожены автоматически.Это свойство C ++, и оно распространяется на все программы.Вот как все будет работать, если вы разместите свою метку в стеке.

{
    QLabel ql = QLabel(some_form); 
    ql.show()
} // scope ends, ql is deleted

delete some_form;
  // ql will be deleted here as well
  // but it's already dead!
  // Program crashes!

Такое распределение в стеке будет означать, что при уничтожении объекта, которому принадлежит метка, метка уже может быть уничтожена.Это приведет к сбою вашей программы.

На самом деле, вы можете иногда создавать объекты в стеке.В функции main вы можете разместить в стеке «основное управление» (обычно это главное окно).Дело в том, что этот объект не будет уничтожен во время выполнения программы, поэтому он может безопасно находиться в стеке до тех пор, пока не выйдет основной - т.е. программа завершится.Вот цитата из руководства по Qt :

 #include <QApplication>
 #include <QPushButton>
 #include <QTranslator>

 int main(int argc, char *argv[])
 {
     QApplication app(argc, argv);

     QTranslator translator;
     translator.load("hellotr_la");
     app.installTranslator(&translator);

     QPushButton hello(QPushButton::tr("Hello world!"));
     hello.resize(100, 30);

     hello.show();
     return app.exec();
 }
13 голосов
/ 05 сентября 2010

Измените

QLabel ql=QLabel();

на

QLabel ql;

и прочитайте книгу на C ++.

4 голосов
/ 05 сентября 2010

Вы можете создавать объекты Qt из стека (без новых), но эти объекты автоматически удаляются, когда они выпадают из области видимости. Например:

void doSomething()
{
    QLabel ql; 
    ql.show()
} // scope ends, ql is deleted

И вот как работает C ++, это не особенность Qt.

3 голосов
/ 05 сентября 2010
QLabel ql;

создает QLabel в стеке. Обратите внимание, что он просто живет до выхода из текущей области.

1 голос
/ 15 сентября 2010

Такой код:

QLabel ql=QLabel();    ql.show()

не скомпилируется, потому что QLabel наследует QObject.И вы не можете сделать копию QObject, потому что его конструктор копирования и операторы присвоения отключены: http://doc.trolltech.com/4.6/qobject.html#no-copy-constructor

Однако,

QLabel ql;

будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...