Какова цель файлов _p.h? - PullRequest
6 голосов
/ 29 июня 2010

В исходных файлах Qt есть две версии файлов заголовков, например:

qxmlstream.h
qxmlstream_p.h

Почему существуют файлы _p.h?

Ответы [ 3 ]

9 голосов
/ 29 июня 2010

Как правило, это частные заголовочные файлы, используемые для того, чтобы компоненты подсистемы знали обо всем, но пользователям это не нужно.

Другими словами, то, что может потребоваться нескольким исходным файлам C в Qt.знать о будет в приватных заголовочных файлах, если пользователям Qt не нужно будет знать о них.

Одним из примеров может быть настраиваемый распределитель памяти для вашей подсистемы.Возможно, вы знаете, что каждое выделение памяти, которое вы делаете, составляет 128 байт, тогда вы можете предоставить такой распределитель:

void * malloc128 (void) { ... }

Поскольку это может иметь сомнительную ценность для пользователей вашей подсистемы, нет смысла публиковать его какчасть официального API, но каждый один из ваших собственных исходных файлов нуждается в прототипе, чтобы вы поместили его в закрытый заголовочный файл.

Тогда ваш собственный код использует:

#include "mysubsystem_p.h"

при использовании пользователями вашего API:

#include "mysubsystem.h"
3 голосов
/ 29 июня 2010

Qt необходимо поддерживать стабильный интерфейс на внешнем канальном уровне. Чтобы решить, что они используют следующий подход:

class MyClass {
public:
  size_t compatSize();
private:
  MyClassPrivate *data;
};


// implementation
struct MyClassPrivate {
  int someFieldThatCanChange;
};
size_t compatSize() { return (size_t)(data->someFieldThatCanChange); }

При этом изменение реализации не влияет на размер и структуру MyClass. И вы по-прежнему можете добавлять новые поля или удалять старые.
Другой подход заключается в использовании «интерфейсов» (абстрактных классов), фабрик и виртуальных функций для каждого метода, что, как мне кажется, приведет к более медленному коду.

0 голосов
/ 10 января 2017

Это можно назвать шаблоном проектирования, используемым для повышения читабельности заголовочных файлов из заданного класса путем сокрытия всего, о чем пользователь класса не должен знать.

Таким образом, вместо определения файла заголовка из заголовка данного класса, который составлен из открытых и закрытых данных, 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;
};

Другими словами, все члены частного класса, таким образом, «экспортируются» в общедоступное определение частного класса.

Для меня это способ сделать заголовочный файл класса, с которым будет работать пользователь, более читабельным. Это особенно верно, когда речь идет о классах, которым нужно много частных членов.

...