在Qt源文件中,有两个版本的头文件,例如:
qxmlstream.h
qxmlstream_p.h
为什么有_p.h文件?
答案 0 :(得分:9)
它们通常是私有头文件,用于使子系统的组件知道除用户不需要的所有内容。
换句话说,如果Qt的用户不需要了解它们,Qt中的多个C源文件可能想知道的内容将在私有头文件中。
一个示例可能是您的子系统的自定义内存分配器。也许您知道您所做的每个内存分配都是128个字节,那么您可以提供这样的分配器:
void * malloc128 (void) { ... }
由于这对您子系统的用户可能具有可疑价值,因此将其作为官方API的一部分发布是没有意义的,但您自己的每个单个源文件都需要原型,因此您将它放在私有头文件中。
然后您自己的代码使用:
#include "mysubsystem_p.h"
,而API的用户使用:
#include "mysubsystem.h"
答案 1 :(得分:3)
Qt需要保持稳定的外部链路级接口。为了解决这个问题,他们使用下一种方法:
class MyClass {
public:
size_t compatSize();
private:
MyClassPrivate *data;
};
// implementation
struct MyClassPrivate {
int someFieldThatCanChange;
};
size_t compatSize() { return (size_t)(data->someFieldThatCanChange); }
通过这样做,实现的更改不会影响MyClass
的大小和结构。您仍然可以添加新字段或删除旧字段
其他方法是为每个方法使用“接口”(抽象类),工厂和虚函数 - 我想这会导致代码变慢。
答案 2 :(得分:0)
这可以称为设计模式,用于通过隐藏类的用户不需要知道的所有内容来提高给定类的头文件的可读性。
因此,Qt不是从由公共和私有数据组成的给定类头定义头文件,而是经常选择将类中的私有数据放入单独的类中。然后将这个单独的类用作原始类的私有成员。
例如,而不是:
class MyClass
{
public:
MyClass();
~MyClass();
QVariant getValue1();
QVariant getValue2();
QVariant getValue3();
private:
QVariant m_Value1;
QVariant m_Value2;
QVariant m_Value3;
};
我们可以拥有以下
class MyClass
{
public:
MyClass();
~MyClass();
QVariant getValue1();
QVariant getValue2();
QVariant getValue3();
private:
friend class MyClassPrivate;
};
其中MyClassPrivate的定义如下
class MyClassPrivate
{
public:
MyClassPrivate ();
~MyClassPrivate ();
QVariant m_Value1;
QVariant m_Value2;
QVariant m_Value3;
};
换句话说,所有私人集体成员因此被出口"进入私人使用类的公共定义。
对我来说,这是一种制作类头文件的方法,用户将处理,更具可读性。当需要大量私人成员的课程时尤其如此。