1.应用程序封装成so动态库时,需要提供头文件,此时为了把私有数据封装起来,就需要把私有数据封装成private的类,把它放在cpp文件而非h文件中,
这样就把私有数据封装起来不给用户看了。
2.在私有数据修改时,不用重新编译所有文件,只需要编译这个动态库就可以了,因为头文件并没有改变。
D指针/私有实现
使用D指针:
class MyClass
{
public:
MyClass();
~MyClass();
private:
MyClassPrivate * const d_ptr;
Q_DECLARE_PRIVATE(MyClass);
};
class MyClassPrivate;
定义了一个指针d_ptr指向私有实现类,然后用Q_DECLARE_PRIVATE宏来定义一些辅助函数和声明友元类:
#define Q_DECLARE_PRIVATE(Class) \
inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \
inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \
friend class Class##Private;
只要在类的头文件中使用这两个宏,就可以通过函数直接得到实体类和句柄类的实际类型了,而且这里还声明了友元,使得数据类和句柄
类连访问权限也不用顾忌了
然后这个私有类的实现如下所示:
class MyClassPrivate
{
public:
MyClassPrivate(MyClass *parent);
private:
MyClass * const q_ptr;
Q_DECLARE_PUBLIC(MyClass);
int myVar;
};
这里的q_ptr指针就是指向公开的接口了,然后Q_DECLARE_PUBLIC宏则定义了辅助函数并声明了友元类:
#define Q_DECLARE_PUBLIC(Class) \
inline Class* q_func() { return static_cast<Class *>(q_ptr); } \
inline const Class* q_func() const { return static_cast<