Qxt中的d-pointer技术及改进
来源:互联网 发布:软件模块结构图 编辑:程序博客网 时间:2024/05/21 23:04
Qxt是一个Qt的扩展库。其中也用到了d-pointer技术,但是与Qt的区别很大,比起Qt有点不足之处。这里我先简单看下它的实现,然后吸取Qt中的优点进行改进。(最新代码在 https://github.com/wang-bin/d-pointer )
之前写过一篇关于d-pointer的文章 http://blog.csdn.net/ibingow/article/details/7522157 ,这里很多细节就不重复了。
在qxtglobal.h中相关代码
/****************************************************************************** This file is derived from code bearing the following notice:** The sole author of this file, Adam Higerd, has explicitly disclaimed all** copyright interest and protection for the content within. This file has** been placed in the public domain according to United States copyright** statute and case law. In jurisdictions where this public domain dedication** is not legally recognized, anyone who receives a copy of this file is** permitted to use, modify, duplicate, and redistribute this file, in whole** or in part, with no restrictions or conditions. In these jurisdictions,** this file shall be copyright (C) 2006-2008 by Adam Higerd.****************************************************************************/#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface<PUB, PUB##Private> qxt_d;#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);#define QXT_D(PUB) PUB##Private& d = qxt_d()#define QXT_P(PUB) PUB& p = qxt_p()template <typename PUB>class QxtPrivate{public: virtual ~QxtPrivate() {} inline void QXT_setPublic(PUB* pub) { qxt_p_ptr = pub; }protected: inline PUB& qxt_p() { return *qxt_p_ptr; } inline const PUB& qxt_p() const { return *qxt_p_ptr; } inline PUB* qxt_ptr() { return qxt_p_ptr; } inline const PUB* qxt_ptr() const { return qxt_p_ptr; }private: PUB* qxt_p_ptr;};template <typename PUB, typename PVT>class QxtPrivateInterface{ friend class QxtPrivate<PUB>;public: QxtPrivateInterface() { pvt = new PVT; } ~QxtPrivateInterface() { delete pvt; } inline void setPublic(PUB* pub) { pvt->QXT_setPublic(pub); } inline PVT& operator()() { return *static_cast<PVT*>(pvt); } inline const PVT& operator()() const { return *static_cast<PVT*>(pvt); } inline PVT * operator->() {return static_cast<PVT*>(pvt); } inline const PVT * operator->() const {return static_cast<PVT*>(pvt); }private: QxtPrivateInterface(const QxtPrivateInterface&) { } QxtPrivateInterface& operator=(const QxtPrivateInterface&) { } QxtPrivate<PUB>* pvt;};
具体不解释了,不难理解。使用时在类定义里加上
QXT_DECLARE_PRIVATE(MyClass)
就会给你生成一个类似于智能指针的成员变量qxt_d,它只是一个借口,真正存放数据的是MyClassPrivate这个类的指针pvt,继承自 QxtPrivate<MyClass>,在qxt_d构造时产生。
私有类的写法是
class MyClassPrivate : public QxtPrivate<MyClass>{....}
一个缺点是派生类不能直接访问基类的数据。可以在 Qxt的源码中看到qxt_d都声明为 private的,而且每个类都有这个成员,并且都是相互独立的,这个就显得有点奇怪了。Qt的做法是数据成员都可以在派生类中访问的,数据被声明为protected,并且Private类可以被继承。
另外一个缺点就是构造一个类可能会分配很多次内存。一个类的第N代派生类构造时会new N次,因为继承链上的每个类都要给自己的private类分配内存。
我对qxt的代码进行了修改,可以解决以上问题,并且使用也更简单。形式上类似于Qt。不详细解释了
//QxtPrivateInterface<PUB, PUB##Private> qxt_d;#define QXT_DECLARE_PRIVATE(PUB) \inline PUB##Private& d_func() { return qxt_d.pri<PUB##Private>(); } \inline const PUB##Private& d_func() const { return qxt_d.pri<PUB##Private>(); } \friend class PUB##Private;#define QXT_DECLARE_PUBLIC(PUB) \inline PUB& q_func() { return *static_cast<PUB*>(qxt_ptr()); } \inline const PUB& q_func() const { return *static_cast<PUB*>(qxt_ptr()); } \friend class PUB;#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);#define QXT_D(PUB) PUB##Private& d = qxt_d.pri<PUB##Private>()#define QXT_P(Class) Class& p = *static_cast<Class*>(qxt_ptr())//interfacetemplate <typename PUB>class QxtPrivate{public:
virtual ~QxtPrivate() {} inline void QXT_setPublic(PUB* pub) { qxt_p_ptr = pub; }protected: inline PUB& qxt_p() { return *qxt_p_ptr; } inline const PUB& qxt_p() const { return *qxt_p_ptr; } inline PUB* qxt_ptr() { return qxt_p_ptr; } inline const PUB* qxt_ptr() const { return qxt_p_ptr; }private: PUB* qxt_p_ptr;};//interfacetemplate <typename PUB, typename PVT>class QxtPrivateInterface{ friend class QxtPrivate<PUB>;public: QxtPrivateInterface(PVT* d):pvt(d) {} QxtPrivateInterface():pvt(new PVT) {} ~QxtPrivateInterface() {if (pvt) {delete pvt;pvt = 0;} } inline void setPublic(PUB* pub) { pvt->QXT_setPublic(pub); } template <typename T> inline T& pri() { return *reinterpret_cast<T*>(pvt); } template <typename T> inline const T& pri() const { return *reinterpret_cast<T*>(pvt); } //static cast requires defination of T inline PVT& operator()() { return *static_cast<PVT*>(pvt); } inline const PVT& operator()() const { return *static_cast<PVT*>(pvt); } inline PVT * operator->() { return static_cast<PVT*>(pvt); } inline const PVT * operator->() const { return static_cast<PVT*>(pvt); }private: QxtPrivateInterface(const QxtPrivateInterface&); QxtPrivateInterface& operator=(const QxtPrivateInterface&); QxtPrivate<PUB>* pvt;};
使用如下:
对于祖先类Base,加上protected成员
class BasePrivate;class Base{public:Base();protected:Base(BasePrivate& d);virtual ~Base();QxtPrivateInterface<Base, BasePrivate> qxt_d;};
如有需要也可以加上宏QXT_DECLARE_PRIVATE(Base),提供访问私有类的简便方法
然后定义BasePrivate,继承自QxtPrivate<Base>
Base的派生类做法类似,只要再定义派生类相应的私有类
class DerivedPrivate : public BasePrivate{}
为减小内存分配次数,派生类中调用基类的构造函数可以使用proteced里的那个。
完
头文件下载(包含如何使用):http://download.csdn.net/detail/ibingow/4765462
- Qxt中的d-pointer技术及改进
- QT中的d-pointer模式分析
- d-pointer
- d-pointer
- 改进Spring中的分页技术
- 改进Spring中的分页技术
- 什么是d-pointer
- SNMPv3协议中的新特性和技术改进简介
- 3D视频技术原理及应用
- Boost 中的smart pointer
- D语言中的内存管理技术
- 3D游戏中的公告牌技术
- D语言中的内存管理技术
- Installing Qxt on Windows
- Qxt的使用
- TI NDK应用开发过程中的一点经验及改进
- TI NDK应用开发过程中的一点经验及改进
- 2D Array and double pointer
- PIL 生成缩略图
- Rhythmbox 导入歌曲乱码
- Ubunut 10.04.3设置Ibus输入法开机启动
- Pro*C中非滚动游标的使用
- 实现输出3个数中最大的一个
- Qxt中的d-pointer技术及改进
- Linux常用网络命令
- SAP中的默认帐户与密码
- Asp.net页面之间传递参数的几种方法
- 打开win7下的项目配置
- 查看和刷新动态库:ldconfig与 /etc/ld.so.conf
- Iphone页面跳转动画的封装
- WithIter 团队 —— 创业切入点
- 实现输出10个数中最大的一个