我什么时候在Qt中使用指针?

时间:2013-09-11 15:50:36

标签: c++ qt pointers

我已经编程了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);

两者都产生一个按钮,但是什么时候应该使用前者而后者呢?这两者有什么区别?

5 个答案:

答案 0 :(得分:11)

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

为什么你宁愿在免费商店中分配内存而不是堆栈,这有两个原因。

  1. 堆栈的大小有限,如果你放弃堆栈预算,你的程序会因堆栈溢出而崩溃。可以在免费存储中分配更多的内存,如果内存分配失败,通常会发生的一切都是抛出bad_alloc异常。
  2. 堆栈上的分配严格地以后进先出(LIFO),这意味着您的按钮不能存在的时间长于分配内存的代码块({...}之间的什么)。当在免费存储中分配内存时,您作为程序员可以完全控制内存保持有效的时间(尽管粗心可能导致内存泄漏)
  3. 在你的情况下,如果按钮只需要在调用函数的持续时间内存在,你可能可以在堆栈上分配按钮;如果按钮需要更长时间有效,坚持免费商店

答案 1 :(得分:7)

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

使用Qt进行内存管理:

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

答案 2 :(得分:2)

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

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

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

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

答案 3 :(得分:1)

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

/** 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()));

该事件将在交付后删除。

答案 4 :(得分:0)

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

相关问题