📜 ⬆️ ⬇️

Subtleties of the implementation of the library code. Part one

When writing a library in C ++, many people face certain difficulties when writing and organizing code. Some already have ready-made solutions, others do not have them and they are trying to find these solutions.

Some of the difficulties in writing library code, more related to “self-documenting,” can be solved with the help of “working” namespaces.

To begin with, we will describe these difficulties and present the usual solutions.
')
Suppose a library implements some entity some_class , which it provides to the library user. The definition of some_class depends on another detail_class library entity , which is part of the implementation and is not provided to the user. The library is supplied only as header files.

The distribution of code by files in this topic is not considered.

Standard solution 1


namespace lib_namespace { class detail_class { }; class some_class { public: //   private: detail_class a_; //    }; } 


Plus this solution:
1) the minimum amount of code required for its implementation.

Minuses:
1) Bad "self-documenting" code. It is not always possible to determine whether they are custom or not by the name of the implementation classes.
2) Jamming the library namespace. Some development environments, when using this namespace, will display what the library user does not need:



Standard solution 2


 namespace lib_namespace { namespace impl { class detail_class { }; }} namespace lib_namespace { class some_class { public: //   private: impl::detail_class a_; //    }; } 

This solution completely removes the shortcomings of the previous approach, but adds its own:
1) the introduction of an additional namespace;
2) In any library class provided to the user and placed in the lib_namespace , it is necessary for all implementation elements to specify the prefix impl ::.

Advantages:
1) good "self-documentation" of the code.

Solution based on "working" namespaces


 namespace work_lib_namespace { class detail_class { }; class some_class { public: //   private: detail_class a_; //    }; } namespace lib_namespace { using ::work_lib_namespace::some_class; } 


All library code is located in the work_lib_namespace namespace. All entities the library provides to the user are added to the main library namespace using using .

The disadvantage of this approach is:
1) the introduction of an additional namespace.

Advantages:
1) “self-documenting” code;
2) the ability to use using namespace some_ns inside the working namespace (even in those library header files that the user directly connects):

 namespace work_lib_namespace { using namespace std; class detail_class { public: //  private: vector<int> data_; }; } 


Conclusion


The presented way of organizing the library allows, on the one hand, to achieve good “self-documenting” of the code, and on the other, to allow library developers to use using namespace not only in cpp implementation files , but also in header files.

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


All Articles