这两种写法的主要区别在于对象的生命周期和存储位置。
-
QFrame *frame = new QFrame(this);
这种写法是在堆上创建一个新的
QFrame
对象。这个对象的生命周期会一直持续到你显式地删除它,或者它的父对象被删除。这种写法常用于 Qt 的父子对象系统,因为 Qt 会自动删除所有的子对象。 -
QFrame frame(this);
这种写法是在栈上创建一个
QFrame
对象。这个对象的生命周期只在当前的作用域内,一旦离开这个作用域,这个对象就会被自动删除。
所以,习惯上我们更倾向于使用 new
在堆上创建对象,这样可以更好地控制对象的生命周期,并利用 Qt 的父子对象系统进行内存管理。
作为对比:
auto *frame1 = new QFrame(this);
frame1->setFrameStyle(QFrame::Box);
frame1->setCursor(Qt::SizeAllCursor);
auto *frame2 = new QFrame(this);
frame2->setFrameStyle(QFrame::Box);
frame2->setCursor(Qt::WaitCursor);
QFrame frame3 (this);
frame3.setFrameStyle(QFrame::Box);
frame3.setCursor(Qt::PointingHandCursor);
auto *grid = new QGridLayout(this);
grid->addWidget(frame1, 0, 0);
grid->addWidget(frame2, 0, 1);
grid->addWidget(&frame3, 0, 2);
在代码中,frame3
是一个局部变量,它在栈上创建。当执行到函数的末尾时,局部变量 frame3
就会被销毁,也就是说 frame3
的生命周期结束了。因此,当你试图在界面上显示 frame3
时,它可能已经被销毁了,所以看不到它。
相反,frame1
和 frame2
是在堆上创建的,它们的生命周期直到显式地删除它们或者它们的父对象被删除时才结束。因此,可以在界面上看到 frame1
和 frame2
。
如果你想让 frame3
在界面上显示,你应该在堆上创建它,就像 frame1
和 frame2
那样:
auto *frame3 = new QFrame(this);
frame3->setFrameStyle(QFrame::Box);
frame3->setCursor(Qt::PointingHandCursor);
然后像之前那样将 frame3
添加到布局中:
grid->addWidget(frame3, 0, 2);
这样,frame3
就会在界面上正确显示了。