锁定老帖子 主题:Qt源码剖析:信息隐藏(2)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-06-04
最后修改:2010-06-04
下面在上一篇的基础上,我们进入Qt的源代码,看看Qt4.x是如何实现 Private Classes 的。 void MyClass::setFoo( int i ) { Q_D(MyClass); d->m_foo = i; } int MyClass::foo() const { Q_D(const MyClass); return d->m_foo; }
class MyObject: public QObject { Q_OBJECT public: MyObject(); virtual ~ MyObject(); void setMemberX( int x ); int memberX() const; void setMemberY( double y); double memberY() const; signals: void priorityChanged( MyObject::Priority priority ); private: int m_memberX; double m_memberY;
class MyObjectPrivate; class MyObject: public QObject { Q_OBJECT public: MyObject(); virtual ~ MyObject(); void setMemberX( int x ); int memberX() const; void setMemberY( double y); double memberY() const; signals: void priorityChanged( MyObject::Priority priority ); protected: MyObjectPrivate * const d_ptr; private: Q_DECLARE_PRIVATE(MyObject); };
class MyClassPrivate;
#include "myclass_p.h"
#define Q_DECLARE_PRIVATE(Class) \ inline Class##Private* d_func() { return reinterpret_cast(qGetPtrHelper(d_ptr)); } \ inline const Class##Private* d_func() const { return reinterpret_cast(qGetPtrHelper(d_ptr)); } \ friend class Class##Private;
inline MyClassPrivate* d_func() { return reinterpret_cast(qGetPtrHelper(d_ptr)); } inline const MyClassPrivate* d_func() const { return reinterpret_cast(qGetPtrHelper(d_ptr)); } friend class MyClassPrivate;
// A template function for getting the instance to your private class instance. template static inline T *qGetPtrHelper(T *ptr) { return ptr; } // A macro for getting the d-pointer #define Q_D(Class) Class##Private * const d = d_func()
下面还是自己展开一下这个宏,就成了
MyClassPrivate * const d = d_func()
简单来说,Qt 为我们把从 d_func() 获取 MyClassPrivate 指针的代码给封装起来了,这样我们就可以比较面向对象的使用 getter 函数获取这个指针了。
现在我们已经比较清楚的知道 Qt 是如何使用 D-Pointer 实现我们前面所说的信息隐藏的了。但是,还有一个问题:如果我们把大部分代码集中到 MyClassPrivate 里面,很可能需要让 MyClassPrivate 的实现访问到 MyClass 的一些东西。现在我们让主类通过 D-Pointer 访问 MyClassPrivate 的数据,但是怎么反过来让 MyClassPrivate 访问主类的数据呢?Qt 也提供了相应的解决方案,那就是 Q_Q 宏,例如:
class MyObjectPrivate { public: MyObjectPrivate(MyObject * parent): q_ptr( parent ), m_priority(MyObject::Low) {} void foo() { // Demonstrate how to make MyObject to emit a signal Q_Q(MyObject); emit q->priorityChanged( m_priority ); } // Members MyObject * const q_ptr; Q_DECLARE_PUBLIC(MyObject); MyObject::Priority m_priority; };
在 private 类 MyObjectPrivate 中,通过构造函数将主类 MyObject 的指针传给 q_ptr。然后我们使用类似主类中使用的 Q_DECLARE_PRIVATE 的宏一样的另外的宏 Q_DECLARE_PUBLIC。这个宏所做的就是让你能够通过 Q_Q(Class) 宏使用主类指针。与 D-Pointer 不同,这时候你需要使用的是 Q_Pointer。这两个是完全相对的,这里也就不再赘述。
现在我们已经能够使用比较 Qt 的方式来使用 Private Classes 实现信息隐藏了。这不仅仅是 Qt 的实现,当然,你也可以不用 Q_D 和 Q_Q,而是使用自己的方式,这些都无关紧要。最主要的是,我们了解了一种 C++ 类的设计思路,这是 Qt 的源代码教给我们的。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 3119 次