《Qt设计DLL》之使用Q_D指针指向私有成员和Q_Q指针指向公开成员

使用Q_D指针指向私有成员和Q_Q指针指向公开成员

开发DLL为什么要使用Q_D/Q_Q指针?
假如,我们要把下面这个类封装成DLL:

class MyClass
{
	public:
	  MyClass();
	  ~MyClass();
	private:
	  int myVar;
};

显然,这个私有成员myVar是我们不想给第三方看到的,而且是代码二进制兼容性的大敌。所以我们使用Q_D指针和Q_D指针,对该私有成员myVar进行私有化。

1、使用d_ptr指针指向MyClass的私有成员

我们定义一个私有类MyClassPrivate,并配合Q_DECLARE_PRIVATE宏,以定义指针d_ptr指向该私有类。

class MyClassPrivate;
class MyClass
{
	public:
	  MyClass();
	  ~MyClass();
	private:
	  MyClassPrivate * const d_ptr;
	  Q_DECLARE_PRIVATE(MyClass);
};

然后,我们把MyClass类中该隐藏的变量塞到私有类MyClassPrivate中,下面展示私有类MyClassPrivate的实现:

class MyClassPrivate
{
	public:
	  MyClassPrivate(MyClass *parent);
	private:
	  MyClass * const q_ptr;
	  Q_DECLARE_PUBLIC(MyClass);
	  int myVar;
};

2、使用q_ptr指针指向MyClass的公有成员

从私有类MyClassPrivate的实现代码可以看到,我们在私有类中,配合Q_DECLARE_PUBLIC宏来定义q_ptr指针指向MyClass的公有成员。

以上就是Qt使用Q_D和Q_Q指针私有实现的基本方法,下面给出一个比较完整的例子:
[ myclass.h]

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QtCore/QObject>
class MyClassPrivate;
class MyClass: public QObject
{
	  Q_OBJECT
	public:
	  MyClass(QObject *parent = 0);
	  virtual ~MyClass();
	  void dummyFunc();
	signal:
	  void dummySignal();
	private:
	  MyClassPrivate * const d_ptr = nullptr;
	  Q_DECLARE_PRIVATE(MyClass);
	  Q_DISABLE_COPY(MyClass);//防止指针d_ptr的二次释放
};
#endif // MYCLASS_H

[myclass.cpp]

#include "myclass.h"
class MyClassPrivate : public QObject
{
	public:
	  MyClassPrivate(MyClass *parent)
	    : q_ptr(parent)
	  {
	  }
	  void foobar()
	  {
	    Q_Q(MyClass);
	    emit q->dummySignal();
	  }
	private:
	  MyClass * const q_ptr;
	  Q_DECLARE_PUBLIC(MyClass);
};
MyClass::MyClass(QObject *parent)
  : QObject(parent)
  , d_ptr(new MyClassPrivate(this))
{
}
MyClass::~MyClass()
{
  Q_D(MyClass);
  delete d;
}
void MyClass::dummyFunc()
{
  Q_D(MyClass);
  d->foobar();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt使用d指针和q指针来实现封装和隐藏内部实现细节,以及提供更好的代码可读性和可维护性。同时,Qt使用命名空间来组织和管理和函数。 下面是一个示例代码,演示了Qt中如何使用d指针、q指针和命名空间: ```cpp // counter.h #ifndef COUNTER_H #define COUNTER_H #include <QObject> namespace MyNamespace { class CounterPrivate; // 前向声明 class Counter : public QObject { Q_OBJECT public: explicit Counter(QObject *parent = nullptr); ~Counter(); void increment(); void decrement(); int value() const; private: CounterPrivate *d_ptr; // d指针 }; } #endif // COUNTER_H // counter.cpp #include "counter.h" namespace MyNamespace { class CounterPrivate { public: int count; }; Counter::Counter(QObject *parent) : QObject(parent), d_ptr(new CounterPrivate) { d_ptr->count = 0; } Counter::~Counter() { delete d_ptr; } void Counter::increment() { ++d_ptr->count; } void Counter::decrement() { --d_ptr->count; } int Counter::value() const { return d_ptr->count; } } // main.cpp #include <QGuiApplication> #include <QQmlApplicationEngine> #include "counter.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); MyNamespace::Counter counter; QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("Counter", &counter); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); } ``` 在这个示例中,我们定义了一个名为Counter的,它位于MyNamespace命名空间中。Counter使用了d指针来隐藏内部实现细节,并提供了increment、decrement和value等公共接口来操作计数器的值。在main.cpp中,我们创建了Counter的实例,并将其作为上下文属性传递给QML引擎。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值