为什么QWidget是通过指针访问的
Why are QWidgets accessed by pointers?
我是Qt5的新手,正在学习QWidget来开发应用程序。
我注意到在许多例子中,QWidget几乎总是通过指针访问的。例如:
#include <QApplication>
#include <QWidget>
#include <QFrame>
#include <QGridLayout>
class Cursors : public QWidget {
public:
Cursors(QWidget *parent = 0);
};
Cursors::Cursors(QWidget *parent)
: QWidget(parent) {
QFrame *frame1 = new QFrame(this);
frame1->setFrameStyle(QFrame::Box);
frame1->setCursor(Qt::SizeAllCursor);
QFrame *frame2 = new QFrame(this);
frame2->setFrameStyle(QFrame::Box);
frame2->setCursor(Qt::WaitCursor);
QFrame *frame3 = new QFrame(this);
frame3->setFrameStyle(QFrame::Box);
frame3->setCursor(Qt::PointingHandCursor);
QGridLayout *grid = new QGridLayout(this);
grid->addWidget(frame1, 0, 0);
grid->addWidget(frame2, 0, 1);
grid->addWidget(frame3, 0, 2);
setLayout(grid);
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Cursors window;
window.resize(350, 150);
window.setWindowTitle("Cursors");
window.show();
return app.exec();
}
这摘自教程:http://zetcode.com/gui/qt5/firstprograms/
然而,在同一页上,我看到我们可以通过其对象本身访问QWidget基类:
#include <QApplication>
#include <QWidget>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWidget window;
window.resize(250, 150);
window.setWindowTitle("Simple example");
window.show();
return app.exec();
}
为什么有必要通过指针访问所有QWidget派生类?为什么没有必要通过指针访问QWidget本身?
这一切都与对象的生存期和共享所有权有关。如果您在函数中的堆栈上创建一个对象,那么当作用域结束时,它将被销毁。
为什么在您的示例中没有必要通过指针访问QWidget?因为当main()"结束"时,程序就结束了,小部件可能会被销毁。
为什么有必要通过指针访问QWidget的孩子?因为如果你想让QWidget允许你访问它的子项,它不会给你一个值,因为它只是一个对象的副本。此外,如果您按值将一个大对象传递给QWidget,它需要复制您的对象。
这并不是QWidgets特有的:它适用于每个QObjects(Qt基本基类,其他一切都是从它派生的)。
这是Qt框架设计选择的结果。报价Qt文件:
QObject既没有复制构造函数,也没有赋值运算符。这是经过设计的。
[…]
主要结果是您应该使用指向QObject的指针(或指向您的QObject子类)否则,您可能会将QObject子类用作一个值。对于例如,如果没有复制构造函数,就不能使用QObject作为要存储在其中一个容器类中的值。你必须存储指针。
来源:
http://doc.qt.io/qt-5.5/qobject.html#no-复制构造函数
这种选择的基本原理在这里解释:
http://doc.qt.io/qt-5.5/object.html#identity-vs 值
QClass的大小更大,您不想通过在堆栈内存中实例化它们来填充堆栈内存。
当您实例化派生类对象时,它还运行基类的构造函数(派生类+基类)。需要内存,
另一方面,QWidget只继承了QObject和QPaintDevice,正如您在这里看到的
因此,在堆栈内存上创建QWidget对象将减少开销。
当你使用堆内存时,你必须非常小心,阅读内存管理上的答案
您可以从这里研究堆栈和堆之间的差异
- 通过指向指针数组的指针访问子类的属性
- 使用指针访问数组中的对象数据成员
- 无法通过指针访问对象的成员
- decltype:使用指针访问类的静态成员
- 是否可以使用指针访问变量以避免直接编辑变量?
- 为什么 C++ 地址中的矢量无法通过原始指针访问
- 使用指针访问数组元素时出现意外结果
- 使用指针访问数组的值
- C++继承从基类指针访问派生类中的非虚拟函数
- 如何使用指针访问成对向量的元素
- 为什么有些库提供无指针访问,而另一些库则不提供
- 如何通过引用或指针访问二维矢量
- 使用指针访问参数接收的结构中的元素时内存泄漏
- 我正在学习C++,我不能使用指针访问参考吗?(举个例子)
- 复制堆栈上的成员值或使用指针访问它?
- C++娜娜 如何从全局列表框*指针访问列表框内的索引 0 上的按钮?
- 通过此指针访问时的成员差异和自身的成员指针(简单的 QT 示例问题)
- 从指针访问 Kaguya Lua 状态
- 说明通过指针访问非静态类成员函数
- 有没有办法使用初始化到第一行的指针访问 2d 数组的第二行?