Qt d指针简单实现及解析

本文详细阐述了C++中面向对象编程的概念、原理及应用,通过实例展示了如何使用C++实现类、对象、继承、多态等核心特性。重点介绍了d指针、private类、invoke方法等关键技术点,以及如何在不同类间进行数据共享和访问。并通过Widget类的实现,演示了如何在实际场景中应用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*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比,欠妥之处,还望海涵






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值