使用C++和Qt创建GUI时,您可以创建一个标签,例如:
QLabel* label = new QLabel("Hey you!", centralWidgetParent);
Run Code Online (Sandbox Code Playgroud)
这会在堆上创建对象并保持在那里,直到我手动删除它或者父进程被销毁.我现在的问题是为什么我需要一个指针呢?为什么不在堆栈上创建它?
//Create a member variable of Class MainWindow
QLabel label;
//Set parent to show it and give a text so the user can see it
QWidget* centralWidget = new QWidget(this); //Needed to add widgets to the window
this->setCentralWidget( centralWidget );
label.setParent(centralWidget);
label.setText( "Haha" );
Run Code Online (Sandbox Code Playgroud)
这工作正常,我可以看到标签,它没有消失.
我们在C++中使用指针让一些东西活得更长,这样我们就可以在各种范围内使用一个对象.但是当我创建一个成员变量时,它会不会停留直到对象被销毁?
编辑:也许我没有说清楚.这是MainWindow类:
class MainWindow : public QMainWindow
{
Q_OBJECT
QLabel label; //First introduced here...
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
//Constructor
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget* centralWidget = new QWidget(this);
this->setCentralWidget( centralWidget );
label.setParent(centralWidget);
label.setText( "Haha" );
}
Run Code Online (Sandbox Code Playgroud)
如果你label超出范围,QLabel::~QLabel将调用析构函数().来自文档:
销毁该对象,删除其所有子对象.
没有必要在堆上创建对象 - 您可以将对象放在堆栈上,但是您需要对对象的生命周期负责(关于在堆上分配数据的问题最大的问题之一是"谁和什么时候应该删除这些对象?",在Qt中它由层次结构处理 - 每当你删除你的小部件时,所有子小部件都将被删除).
为什么你的程序工作 - 我不知道 - 它可能不起作用(label在范围的最后被销毁).另一个问题是 - label如果您没有对它的引用,您将如何更改(例如某些插槽中)的文本?
编辑我刚刚看到你label是你的成员MainWindow.拥有一个完整的对象,而不是作为类成员的对象的指针是完全没问题的,因为它不会被破坏MainWindow.请注意,如果你创建这样的实例MainWindow:
MainWindow *w = new MainWindow();
Run Code Online (Sandbox Code Playgroud)
label 将在堆上创建.
因为这就是 Qt 的设计方式。我意识到这不是一个非常令人满意的答案,但 Qt 只是被设计为“在堆上创建小部件,父母负责删除他们的孩子”。
意识到 Qt 的起源是古老的,比我们认为的“现代 C++”还要古老。
要记住的另一件事是 Qt 使用所谓的 pimpl 范式,其中对象数据在您实际实例化的类之后隐式共享和管理。见这里:http : //qt-project.org/wiki/Dpointer
最重要的是,如果您在堆栈上进行分配以避免使用堆,那么 Qt 只是在您身上拉了一个快速分配并使用堆。
| 归档时间: |
|
| 查看次数: |
3211 次 |
| 最近记录: |