в исходных файлах Qt, есть две версии заголовочных файлов, таких как:Что такое _p.h файлы?
qxmlstream.h
qxmlstream_p.h
Почему там _p.h файлы?
в исходных файлах Qt, есть две версии заголовочных файлов, таких как:Что такое _p.h файлы?
qxmlstream.h
qxmlstream_p.h
Почему там _p.h файлы?
Они обычно являются закрытыми файлами заголовков, которые используются для того, чтобы компоненты подсистем знали обо всем, кроме пользователей, которые не нуждаются.
Другими словами, что-то, что несколько исходных файлов C в Qt, возможно, захотят узнать, было бы в закрытых заголовочных файлах, если бы пользователям Qt не нужно было знать о них.
Одним из примеров может быть специализированный распределитель памяти для вашей подсистемы. Возможно, вы знаете, что каждое распределение памяти вы сделаете 128 байт, то вы можете предоставить такой аллокатор:
void * malloc128 (void) { ... }
Так как это, вероятно, будут сомнительной ценность для пользователей вашей подсистемы, нет никакого смысла публиковать его в качестве части официальный API, но каждый одному из ваших собственных исходных файлов нужен прототип, чтобы вы поместили его в закрытый заголовочный файл.
Тогда ваш собственный код использует:
#include "mysubsystem_p.h"
в то время как пользователи вашего использования API:
#include "mysubsystem.h"
Qt необходимо поддерживать стабильный внешний интерфейс канального уровня. Для того, чтобы решить, что они используют следующий подход:
class MyClass {
public:
size_t compatSize();
private:
MyClassPrivate *data;
};
// implementation
struct MyClassPrivate {
int someFieldThatCanChange;
};
size_t compatSize() { return (size_t)(data->someFieldThatCanChange); }
Делая это изменение реализации не влияет на размер и структуру MyClass
. И вы все еще можете добавлять новые поля или удалять старые.
Другим подходом является использование «интерфейсов» (абстрактных классов), фабрик и виртуальных функций для каждого метода, что, я думаю, приведет к более медленному коду.
Это можно назвать шаблоном проектирования, используемым для повышения удобочитаемости файлов заголовков из данного класса, спрятав все, о чем не должен знать пользователь класса.
Таким образом, вместо определения файла заголовка из данного заголовка класса, который состоит из публичных и частных данных, 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;
};
Другими словами, все частные члены класса поэтому «экспортируются» в публичное определение частного класса.
Для меня это способ сделать заголовочный файл класса, с которым будет работать пользователь, более читаемым.Это особенно актуально, когда речь идет о занятиях, требующих большого количества частных членов.