您的位置:首页 > 编程语言 > Qt开发

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比,欠妥之处,还望海涵
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: