Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Namespaces and packaging in C++

What is the best/cleanest way to use namespaces in packaged code?

E.g. in libraries like boost there seem to be very organized namespaces management, some techniques are used that allow to disambiguate names. The important thing, however, is that one won't see much code like

typedef namespace1::namespace2::sth_else::a_class<namespace3::namespace4::b_class> type;

usually, there's not much cross-namespacing, which indicates good architecture but also a good namespace management. The question is: what IS the good namespace management?

Say we have file structure like this:

component1/...  (depends on reusable_if)
component2/...  (depends directly on reusable_if and on component 1)
reusable/
reusable/some_part/
reusable/some_part/...
reusable/some_other_part/
reusable/some_other_part/...
reusable/SthThatUsesBothReusableParts.h   (implements reusable_if/ISth.h)
reusable/SthThatUsesBothReusableParts.cpp (implements reusable_if/ISth.h)
reusable_if/
reusable_if/ISth.h   (pure abstract class)
reusable_if/ISthElse.h (pure abstract class)
main.cpp (e.g. instantiates SthThatUsesBothReusableParts and passes to component1/2)

The reason why there is reusable_if/ folder is because both component1 and component2 want to reuse the same interfaces (hence none of them 'owns' the interfaces exclusively). Also, the assumption is that the project is indeed very big and needs proper namespaces for classes in each of the folders.

How would you apply namespaces in such a project? Say I declare all classes in reusable/ in namespace ::reusable. Should I put interfaces from reusable_if into namespace ::reusable or into ::reusable_if? Or maybe into none since it is used by component1 and component2?

What about namespaces in component1 and component2? Anything to remember? What about keyword using? Let's say that I decide to add this ::reusable_if namespace. Can I put using reusable_if into header files in component1 and component2, provided that using ... is placed inside namespace ::component1 and ::component2?

I am open to any suggestions, also those not necessarily related to the above example.

like image 395
Andrew Avatar asked Feb 06 '13 09:02

Andrew


People also ask

What is difference between namespace and package?

Packages are used in Java in order to prevent naming conflicts, to control access, to make searching/locating and usage of classes, interfaces, enumerations and annotations easier, etc. A namespace is designed for providing a way to keep one set of names separate from another.

What is namespace in package?

Namespace packages allow you to split the sub-packages and modules within a single package across multiple, separate distribution packages (referred to as distributions in this document to avoid ambiguity).

What are namespaces in C?

A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.

Is namespace similar to package?

The main difference between namespace and package is that namespace is available in C# (. NET) to organize the classes so that it is easier to handle the application, while package is available in Java and groups similar type of classes and interfaces to improve code maintainability.


1 Answers

Personal opinion disclaimer. Your question basically asks for subjective answers, and will probably be closed for it, but I'll give it a shot.


Namespaces are primarily useful to avoid identifier clashes. There is "your" namespace (mylib::), and the namespaces of everybody else (std::, boost::, icu::, ...), and that is about as far as namespaces should be taken.

There is little benefit to be had by subdividing your project (as in, "your team's project") into sub-namespaces, unless you get a problem with identifier clashes -- in which case you should reconsider your strategy of calling your classes X and Y. ;-)

Things are a bit different in huge libs, like Boost. They effectively consist of many different projects, maintained by seperate teams, so there's a problem of project-specific identifiers clashing with each other if they were all lumped into boost:: (and the clash possibly not showing up in casual testing).

If you stop looking at boost::filesystem as a "sub-namespace", and instead look at boost:: as an "identity wrapper" for the individual projects filesystem::, thread::, program_options:: and whatnot, so that they look more "Boost-ish", the picture becomes clearer.

like image 165
DevSolar Avatar answered Sep 30 '22 13:09

DevSolar