为什么我们不能在没有new关键字的情况下在Qt中创建对象(即在堆栈上)?

时间:2021-02-24 20:51:32

Why can't we create object in QT without the new keyword? Usually we create pointer to an object, like this:

为什么我们不能在没有new关键字的情况下在QT中创建对象?通常我们创建指向对象的指针,如下所示:

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

But I want to create an object like this:

但我想创建一个这样的对象:

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

Is it possible?

可能吗?

5 个解决方案

#1


19  

The thing is that the Qt controls (labels, buttons) are in a hierarchy (buttons belong to forms, for example). And the way Qt is implemented requires that when an object is destroyed, all objects that belong to it are destroyed as well.

问题是Qt控件(标签,按钮)位于层次结构中(例如,按钮属于表单)。实现Qt的方式要求当一个对象被销毁时,属于它的所有对象也会被销毁。

If you place objects on a stack (that's how "create without new keyword" is really called), they will be destroyed automatically. That's the property of C++, and it holds for all programs. Here's how the things would work if you allocated your label on the stack.

如果您将对象放在堆栈上(这就是“无需创建新关键字”的方法),它们将被自动销毁。这是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!

Such stack allocation would mean that when you destroy the object the label belongs to, the label might already have been destroyed. It will make your program crash.

这样的堆栈分配意味着当您销毁标签所属的对象时,标签可能已经被销毁。它会让你的程序崩溃。

Actually, you can sometimes create objects on stack. In the main function, you may allocate on stack your "main control" (usually it's the main window). The thing is that this object won't be destroyed during the program execution, so it can safely be on stack until main exits--i.e. the program terminates. Here's a quote from Qt tutorial:

实际上,您有时可以在堆栈上创建对象。在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();
 }

#2


14  

Change

QLabel ql=QLabel();

to

QLabel ql;

and read some C++ book.

并阅读一些C ++书籍。

#3


3  

You can create Qt objects from stack (without new) but those objects are automatically deleted when they fall out of scope. For example:

您可以从堆栈创建Qt对象(没有新的)但这些对象在超出范围时会自动删除。例如:

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

And that's how C++ works, it's not a Qt specific feature.

这就是C ++的工作原理,它不是Qt特有的功能。

#4


2  

QLabel ql;

creates a QLabel on the stack. Note that it just lives until the current scope exits.

在堆栈上创建一个QLabel。请注意,它只会在当前作用域退出之前存在。

#5


0  

Such code:

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

won't compile, because QLabel inherits QObject. And you can't make a copy of QObject, because its copy constructor and assignment operators are disabled: http://doc.trolltech.com/4.6/qobject.html#no-copy-constructor

不会编译,因为QLabel继承了QObject。并且您无法复制QObject,因为它的复制构造函数和赋值运算符被禁用:http://doc.trolltech.com/4.6/qobject.html#no-copy-constructor

However,

QLabel ql;

will work.

#1


19  

The thing is that the Qt controls (labels, buttons) are in a hierarchy (buttons belong to forms, for example). And the way Qt is implemented requires that when an object is destroyed, all objects that belong to it are destroyed as well.

问题是Qt控件(标签,按钮)位于层次结构中(例如,按钮属于表单)。实现Qt的方式要求当一个对象被销毁时,属于它的所有对象也会被销毁。

If you place objects on a stack (that's how "create without new keyword" is really called), they will be destroyed automatically. That's the property of C++, and it holds for all programs. Here's how the things would work if you allocated your label on the stack.

如果您将对象放在堆栈上(这就是“无需创建新关键字”的方法),它们将被自动销毁。这是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!

Such stack allocation would mean that when you destroy the object the label belongs to, the label might already have been destroyed. It will make your program crash.

这样的堆栈分配意味着当您销毁标签所属的对象时,标签可能已经被销毁。它会让你的程序崩溃。

Actually, you can sometimes create objects on stack. In the main function, you may allocate on stack your "main control" (usually it's the main window). The thing is that this object won't be destroyed during the program execution, so it can safely be on stack until main exits--i.e. the program terminates. Here's a quote from Qt tutorial:

实际上,您有时可以在堆栈上创建对象。在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();
 }

#2


14  

Change

QLabel ql=QLabel();

to

QLabel ql;

and read some C++ book.

并阅读一些C ++书籍。

#3


3  

You can create Qt objects from stack (without new) but those objects are automatically deleted when they fall out of scope. For example:

您可以从堆栈创建Qt对象(没有新的)但这些对象在超出范围时会自动删除。例如:

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

And that's how C++ works, it's not a Qt specific feature.

这就是C ++的工作原理,它不是Qt特有的功能。

#4


2  

QLabel ql;

creates a QLabel on the stack. Note that it just lives until the current scope exits.

在堆栈上创建一个QLabel。请注意,它只会在当前作用域退出之前存在。

#5


0  

Such code:

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

won't compile, because QLabel inherits QObject. And you can't make a copy of QObject, because its copy constructor and assignment operators are disabled: http://doc.trolltech.com/4.6/qobject.html#no-copy-constructor

不会编译,因为QLabel继承了QObject。并且您无法复制QObject,因为它的复制构造函数和赋值运算符被禁用:http://doc.trolltech.com/4.6/qobject.html#no-copy-constructor

However,

QLabel ql;

will work.