何时在Qt中使用指针

When do I use pointers in Qt?

本文关键字:指针 Qt 何时      更新时间:2023-10-16

我已经编程Qt一段时间了,我想知道这两种情况有什么区别:

案例1:

页眉:

QPushButton * button;

源文件:

button = new QPushButton(this);
button->setText("Button");
button->resize(100,100);

案例2:

页眉:

QPushButton button;

源:

button.setParent(this);
button.setText("Button");
button.resize(100,100);

两者都会产生一个按钮,但是我应该何时使用前者,何时使用后者?两者之间有什么区别?

第一种情况和第两种情况之间的区别在于,当您使用指针和 new 语句来分配按钮时,按钮的内存在免费存储区(堆)中分配。在第二条语句中,内存在堆栈上分配。

您宁愿在免费存储中分配内存而不是堆栈有两个原因。

    堆栈
  1. 的大小有限,如果您超出堆栈预算,您的程序将因堆栈溢出而崩溃。可以在免费存储中分配更多的内存,如果内存分配失败,通常发生的只是抛出bad_alloc异常。
  2. 堆栈上的分配严格来说是后进先出 (LIFO),这意味着您的按钮存在的时间不能超过分配内存的代码块({...}之间的代码块)。在免费存储中分配内存时,作为程序员可以完全控制内存保持有效的时间(尽管粗心会导致内存泄漏)
在您的情况下,如果按钮

只需要在调用函数的持续时间内存在,那么在堆栈上分配按钮可能就可以了;如果按钮需要有效期更长,请坚持免费商店。

Qt内存管理适用于对象的层次结构,当父对象在销毁时自动删除子对象时。这就是为什么Qt程序在类似情况下总是使用指针的原因。

使用 Qt 进行内存管理:

Qt维护对象的层次结构。对于小部件(可见元素),这些层次结构表示小部件本身的堆叠顺序,对于非小部件,它们仅表示对象的"所有权"。Qt删除子对象及其父对象。

在第一种情况下,您正在动态分配按钮(这意味着当父按钮被销毁时,它将被销毁)。在第二种情况下,当代码块结束时,按钮将消失(这意味着它超出了范围)。

当您想QObject时,请使用第一个,您所指的,而不仅仅是创建它的块。

在您所引用的类的上下文中(假设button在这两种情况下都是成员变量),它没有太大区别。

此外,您可能希望在使用多态性时使用指针。

一个有用的特定用法:发布自定义事件时,携带详细数据,例如:

/** support SWI... prolog_edit:edit_source(File) */
struct reqEditSource : public QEvent {
    QString file;
    QByteArray geometry;
    reqEditSource(QString file, QByteArray geometry = QByteArray())
        : QEvent(Type(User+1)), file(file), geometry(geometry) {}
};

您可以"解雇并忘记"它们:

qApp->postEvent(this, new reqEditSource(files[i], p.value(k).toByteArray()));

该事件将在传递后被删除。

Qt中的许多函数将对象作为参数,实际上采用指向对象的指针。这是因为"按值"传递对象实际上会创建对象的副本(通过复制构造函数)并传递该副本!创建对象的新副本会产生大量开销。同时,"通过引用"传递对象,即作为指针,将只传递一个 32 位内存地址,这是一个非常轻量级的操作。