Qt d指针简单实现及解析
2012-07-16 16:27
351 查看
[cpp] view
plaincopy
/*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
[cpp] view
plaincopy
/*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
[cpp] view
plaincopy
/*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()
{
}
[cpp] view
plaincopy
/*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
[cpp] view
plaincopy
/*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
[cpp] view
plaincopy
/*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;
}
[cpp] view
plaincopy
/*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比,欠妥之处,还望海涵
plaincopy
/*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
[cpp] view
plaincopy
/*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
[cpp] view
plaincopy
/*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()
{
}
[cpp] view
plaincopy
/*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
[cpp] view
plaincopy
/*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
[cpp] view
plaincopy
/*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;
}
[cpp] view
plaincopy
/*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比,欠妥之处,还望海涵
相关文章推荐
- Qt d指针简单实现及解析--威力加强版
- Qt d指针简单实现及解析--威力加强版
- Qt d指针简单实现及解析
- 解析智能指针底层简单实现
- Qt实现SAX2方式解析XML文件(简单有效、老少皆宜,200MB大小4-7层的XML解析只需要30s)
- C++ 几种智能指针的简单实现
- QT学习之三---定义窗口并实现简单布局
- Makefile解析和简单的进度条实现
- QT实现简单验证的页面跳转
- QT实现简单的抽奖界面
- XML--- 简单的DOM解析XML文件,并实现增,删,查,改的操作
- Qt 中使用freeType2实现简单的文本渲染
- Skinned Mesh原理解析和一个最简单的实现示例
- Qt实现图片的简单压缩
- Js解析xml文件并简单实现省市区级联菜单(并解决各浏览器兼容性问题).
- 利用Gson实现简单的json字符串解析
- Qt for Android QML实现缩放、拖拽、长按效果简单示例
- 通过正则表达式实现简单xml文件解析
- jquery绑定原理 简单解析与实现代码分享
- Ubuntu 安装 Qt 开发环境 简单实现