QT中的数据指针

 在此中以QGLWidget为例作为一个说明:

在源码头文件中看到该类的声明部分,第二行就是

DECLARE_PRIVATE(QGLWidget)

这是一个宏的定义,展开以后是这个样子的:

#define Q_DECLARE_PRIVATE(Class) /
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr); } /
    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(d_ptr); } /
    friend class Class##Private;

也就是说定义了一个内联函数去得到一个私有数据成员的指针,大家在这里会得到将d_ptr强制转换而来的一个指针。指针的类型为QGLWidgetPrivate(这里的##是将前后连接起来的,编译器所完成的工作,我这里是以QGLWidget为例的,所以是QGLWidgetPrivate数据),我在看这里的时候有个疑问是这个数据指针存在于哪里,什么时候被分配了内存空间的。

下面是我的解释:

我们在调用QGLWidget的构造函数时,会先调用基类即QWidget的构造函数,我们其实是这样调用的:

QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
    : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)

大家看到这里在构造QWidget时,给数据成员分配了内存空间,而这个构造函数实际上是按下面定义的:

QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
    : QObject(dd, 0), QPaintDevice()
{
    d_func()->init(parent, f);
}

依此类推,我们有理由相信,这个数据指针最终指向的是QObject中所定义的一个指针d_ptr。另外,我们还可以看到,这些最后带有Private的类也是有继承关系的,这就解释了,在各个类中d_ptr是如何呈现自身的特性的。

另外还有一点就是QGLWidgetPrivate中的数据又是在何时被初始化的呢,是在一个init函数中被初始化的,其调用如下显示:

QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
    : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
{
    Q_D(QGLWidget);     //这里获得了数据指针(据前面的解释)
    setAttribute(Qt::WA_PaintOnScreen);
    setAttribute(Qt::WA_NoSystemBackground);
    setAutoFillBackground(true); // for compatibility
    d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget); //这里对其进行初始化
}

还有两点需要注意的是,两个宏:

#define Q_DECLARE_PUBLIC(Class)                                    /
    inline Class* q_func() { return static_cast<Class *>(q_ptr); } /
    inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } /
    friend class Class;

这个宏被用于数据类中调用去得到其所对应的实体类(例如:QGLWidgetPrivate对应于QGLWidget)

#define Q_DECLARE_PRIVATE(Class) /
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr); } /
    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(d_ptr); } /
    friend class Class##Private;

这个宏刚好与之前的宏相反,用于实体类用于得对应的数据类成员。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt ,信号和槽是一种用于对象间通信的机制。它们允许一个对象发出信号,另一个对象可以接收这个信号并做出相应的处理。当一个对象发出信号时,它可以传递任何类型的数据,包括指针。在信号槽机制,信号和槽的参数必须匹配,否则编译会失败。 如果想传递局部数据指针,需要注意以下几点: 1. 局部指针变量在函数执行完毕后就会被销毁,因此不能直接把指针作为参数传递给信号槽。 2. 如果需要在信号槽使用局部指针变量,需要将其分配在堆上,以确保在执行完函数后仍然存在。 3. 在信号槽的调用,如果使用了堆上的指针,一定要注意释放内存,否则会导致内存泄漏。 下面是一个例子,演示如何在信号槽传递局部数据指针: ```c++ class MyClass : public QObject { Q_OBJECT public slots: void mySlot(MyObject *obj) { // process obj pointer here delete obj; // don't forget to release memory } signals: void mySignal(MyObject *obj); }; void MyClass::myFunction() { MyObject *obj = new MyObject(); // allocate on heap emit mySignal(obj); // emit signal with obj pointer } ``` 在上面的例子,MyClass 的 myFunction() 函数会在堆上分配一个 MyObject 对象,并将其指针传递给 mySignal() 信号。当该信号被触发时,会调用 mySlot() 槽函数,并将指针作为参数传递给它。在 mySlot() ,可以使用指针进行任何处理,并在处理完成后释放内存。 需要注意的是,在信号槽传递指针需要特别小心,因为它涉及到内存管理和资源释放问题。确保在使用完指针后及时释放内存,避免内存泄漏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值