What is the purpose of _p.h files?

There are two versions of header files in the Qt source files, for example:

qxmlstream.h qxmlstream_p.h 

Why do _p.h files exist?

+4
source share
3 answers

They are usually private header files that are used to make subsystem components aware of everything, but users do not need it.

In other words, what a few C source files in Qt might want to know would be in the private header files if Qt users did not need to know about them.

One example would be a dedicated memory allocator for your subsystem. Perhaps you know that each memory allocation you allocate is 128 bytes, then you can provide such a allocator:

 void * malloc128 (void) { ... } 

Since this is likely to be of dubious value to users of your subsystem, it makes no sense to publish it as part of the official API, but each of your own source files needs a prototype so that you put it in a private header file.

Then your own code uses:

 #include "mysubsystem_p.h" 

while your API users use:

 #include "mysubsystem.h" 
+8
source

Qt must support a stable external link-level interface. To solve this problem, they use the following approach:

 class MyClass { public: size_t compatSize(); private: MyClassPrivate *data; }; // implementation struct MyClassPrivate { int someFieldThatCanChange; }; size_t compatSize() { return (size_t)(data->someFieldThatCanChange); } 

Performing this implementation change does not affect the size and structure of MyClass . And you can still add new fields or delete old ones.
Another approach is to use β€œinterfaces” (abstract classes), factories, and virtual functions for each method, which, in my opinion, will lead to slower code.

+2
source

This can be called a design pattern used to increase the readability of header files from this class, hiding everything that the class user should not know about.

So, instead of defining a header file from a given class header, which consists of public and private data, Qt often decides to put private data from the class into a separate class. This separate class is then used as a private member from the source class.

For example, instead of:

 class MyClass { public: MyClass(); ~MyClass(); QVariant getValue1(); QVariant getValue2(); QVariant getValue3(); private: QVariant m_Value1; QVariant m_Value2; QVariant m_Value3; }; 

We could have the following

 class MyClass { public: MyClass(); ~MyClass(); QVariant getValue1(); QVariant getValue2(); QVariant getValue3(); private: friend class MyClassPrivate; }; 

where MyClassPrivate is defined as follows

 class MyClassPrivate { public: MyClassPrivate (); ~MyClassPrivate (); QVariant m_Value1; QVariant m_Value2; QVariant m_Value3; }; 

In other words, all private members of a class are therefore "exported" to the public definition of a private class.

For me, this is a way to make the class header file that the user will work with more readable. This is especially true when it comes to classes requiring a large number of private members.

0
source

Source: https://habr.com/ru/post/1314192/


All Articles