- /*object.h*/
- #ifndef _OBJECT_H_
- #define _OBJECT_H_
- #define INVOKE_METHOD_PRIVATE(Class) Class##Private *d_func() {return reinterpret_cast<Class##Private*>(d_ptr);}//reinterpret_cast将转换后的类型值转换回原始类型
- #define Q_D(Class) Class##Private* d = d_func()
- class ObjectData;
- class ObjectPrivate;
- class Object
- {
- INVOKE_METHOD_PRIVATE(Object)
- public:
- Object();//这个构造函数是给直接使用(定义)Object自己具体行为用的
- ~Object();
- Object(ObjectPrivate &dd);//这个构造函数是给Object的子类初始时顺带初始Object用的
- protected:
- ObjectData* d_ptr;
- };
- #endif
- /*object_p.h*/
- #ifndef _OBJECT_P_H_
- #define _OBJECT_P_H_
- class ObjectData//所有数据类的抽象类
- {
- public:
- virtual ~ObjectData() {}
- };
- class ObjectPrivate : public ObjectData
- {
- public:
- ObjectPrivate();//Object自己的数据类
- ~ObjectPrivate();
- };
- #endif
- /*object.cpp*/
- #include "object.h"
- #include "object_p.h"
- Object::Object()
- :d_ptr(new ObjectPrivate)
- {
- }
- Object::Object(ObjectPrivate &dd)
- :d_ptr(&dd)
- {
- }
- Object::~Object()
- {
- }
- ObjectPrivate::ObjectPrivate()
- {
- }
- ObjectPrivate::~ObjectPrivate()
- {
- }
- /*widget.h*/
- #ifndef _WIDGET_H_
- #define _WIDGET_H_
- #include <iostream>
- #include "object.h"
- using namespace std;
- class WidgetPrivate;//Widget自己的数据类
- class Widget : public Object
- {
- INVOKE_METHOD_PRIVATE(Widget)
- public:
- Widget();
- ~Widget();
- void setWidth(int);//set方法
- void setHeight(int);
- int getWidth();//get方法
- int getheight();
- };
- #endif
- /*widget_p.h*/
- #ifndef _WIDGET_P_H_
- #define _WIDGET_P_H_
- #include "object_p.h"
- class WidgetPrivate : public ObjectPrivate
- {
- public:
- int nWidth;
- int nHeight;
- };
- #endif
- /*widget.cpp*/
- #include "widget.h"
- #include "widget_p.h"
- Widget::Widget()
- :Object(*new WidgetPrivate)
- {
- }
- Widget::~Widget()
- {
- }
- void Widget::setWidth(int n)
- {
- Q_D(Widget);//获得自己的数据类指针,d指针就是个临时的变量
- d->nWidth = n;
- }
- void Widget::setHeight(int n)
- {
- Q_D(Widget);
- d->nHeight = n;
- }
- int Widget::getWidth()
- {
- Q_D(Widget);
- return d->nWidth;
- }
- int Widget::getheight()
- {
- Q_D(Widget);
- return d->nHeight;
- }
- /*main.cpp*/
- #include "widget.h"
- int main()//测试
- {
- Widget w;
- w.setWidth(6);
- w.setHeight(7);
- std::cout<<"width : "<<w.getWidth()<<std::endl;
- std::cout<<"height : "<<w.getheight()<<std::endl;
- system("pause");
- return 0;
- }
1.d指针其实就是对应类的数据类指针,这个类一般后面都是Private字样
2.INVOKE_METHOD_PRIVATE解析之后就得到了一个私有的成员函数
3.Q_D解析之后就是调用上面这个私有的成员函数
4.为什么用reinterpret_cast?因为此处首先可以肯定这个d_ptr的转换是在父类,子类,孙子类...之间进行的,考虑两种情况,要么d_ptr是new ObjectPrivate,转换后转为自己,是安全的,要么d_ptr = new WidgetPrivate,转换后转为ObjectPrivate* ,也是安全的。剩下的情况也一样。
5.为什么要转换,直接用不就行了吗?直接用的话,让我想起了多态,d_ptr的确是自己或者子类初始化的,不过虚函数在哪,不可能为了访问子类的成员,我要添加n多虚函数把....
6.h文件里面用到了前向声明,因为对声明的类,并没有具体使用它,而是把它作为参数类型,或者返回值,这是安全的
7.Widget_p.h文件里的类的实现在Widget.cpp里面,为什么?这个还真不太了解,可能是为了节省文件数,或者是为了那个q指针的方便访问,因为这篇文章还没有考虑到q指针,可能那个时候,这一条的特点就体现出来了
8.毕竟不能和Qt比,欠妥之处,还望海涵