为什么QWidgets是通过指针访问的?
Why are QWidgets accessed by pointers?
我是 Qt5 的新手,正在学习 QWidgets 来开发应用程序。
我在很多例子中注意到,QWidgets 几乎总是通过指针访问。例如:
#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 基 class:
#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 派生的 classes?为什么不需要通过指针访问 QWidget 本身?
QClasses 的大小更大,您不想通过在堆栈内存中实例化它们来填满堆栈内存。
当您实例化派生 class 对象时,它还会运行基础 class 的构造函数(派生 class + 基础 class )需要内存,
另一方面,如您所见,QWidget 仅继承 QObject 和 QPaintDevice here
因此在堆栈内存上创建 QWidget 对象的开销会更少。
使用堆内存时必须非常小心,阅读 memory management
上的答案
你可以从here
研究stack和heap的区别
这一切都与 object 的生命周期和共享所有权有关。如果你在函数中的堆栈上创建了一个object,它会在作用域结束时被销毁。
为什么在您的示例中不需要通过指针访问 QWidget?只是因为当main()'ends',你的程序结束了,widget可能会被销毁
为什么要通过指针访问QWidget的children?因为如果你想让 QWidget 给你访问它的 child,它不能给你一个值,因为它只是一个 object 的副本。此外,如果你将一个大的 object 按值传递给 QWidget,它需要复制你的 object.
这不是特定于 QWidgets:每个 QObjects 都是如此(Qt 基础 class,其他所有内容都从中派生)。
这是Qt框架设计选择的结果。引用 Qt 文档:
QObject has neither a copy constructor nor an assignment operator.
This is by design.
[...]
The main consequence is that you should use
pointers to QObject (or to your QObject subclass) where you might
otherwise be tempted to use your QObject subclass as a value. For
example, without a copy constructor, you can't use a subclass of
QObject as the value to be stored in one of the container classes. You
must store pointers.
来源:
http://doc.qt.io/qt-5.5/qobject.html#no-copy-constructor
此选择的理由解释如下:
我是 Qt5 的新手,正在学习 QWidgets 来开发应用程序。
我在很多例子中注意到,QWidgets 几乎总是通过指针访问。例如:
#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 基 class:
#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 派生的 classes?为什么不需要通过指针访问 QWidget 本身?
QClasses 的大小更大,您不想通过在堆栈内存中实例化它们来填满堆栈内存。
当您实例化派生 class 对象时,它还会运行基础 class 的构造函数(派生 class + 基础 class )需要内存,
另一方面,如您所见,QWidget 仅继承 QObject 和 QPaintDevice here
因此在堆栈内存上创建 QWidget 对象的开销会更少。
使用堆内存时必须非常小心,阅读 memory management
上的答案你可以从here
研究stack和heap的区别这一切都与 object 的生命周期和共享所有权有关。如果你在函数中的堆栈上创建了一个object,它会在作用域结束时被销毁。
为什么在您的示例中不需要通过指针访问 QWidget?只是因为当main()'ends',你的程序结束了,widget可能会被销毁
为什么要通过指针访问QWidget的children?因为如果你想让 QWidget 给你访问它的 child,它不能给你一个值,因为它只是一个 object 的副本。此外,如果你将一个大的 object 按值传递给 QWidget,它需要复制你的 object.
这不是特定于 QWidgets:每个 QObjects 都是如此(Qt 基础 class,其他所有内容都从中派生)。
这是Qt框架设计选择的结果。引用 Qt 文档:
QObject has neither a copy constructor nor an assignment operator. This is by design.
[...]
The main consequence is that you should use pointers to QObject (or to your QObject subclass) where you might otherwise be tempted to use your QObject subclass as a value. For example, without a copy constructor, you can't use a subclass of QObject as the value to be stored in one of the container classes. You must store pointers.
来源:
http://doc.qt.io/qt-5.5/qobject.html#no-copy-constructor
此选择的理由解释如下: