[C++] "Private" namespace, is this customary?

Started by
9 comments, last by mrbastard 15 years, 8 months ago
This is a really quick question: I've realized that my design requires a global object. I thought about creating a "private" namespace within my library where this global object will reside.

namespace MyLibraryNamespace
{
    namespace MyLibraryPrivateNamespace
    {
        // Global variable
    }
}
Is this a customary way to hide implementation details like this?
Advertisement
How many different parts of your code need access to this global object?

If it's only required within a single CPP file, then I'd use an anonymous namespace.
#include "myHeader.h"using namespace MyLibrary;namespace//anonymous{  GlobalObject g_Object;}...
Quote:Original post by Hodgman
How many different parts of your code need access to this global object?

If it's only required within a single CPP file, then I'd use an anonymous namespace.


Unfortunately it needs to be accessed from a couple different translation units.

My class also seems like a candidate to be a singleton:

(1) Bad things happen if more than one is instantiated
(2) It needs to be global

... are there any generic singleton classes that I can use? I've searched boost already.
you could always change your design. /snippy comment
Quote:Original post by thedustbustr
you could always change your design. /snippy comment


Can't, its an abstract representation of a piece of hardware, plus I have to work with some unfortunate "restrictions" (aka design flaws) of libraries I'm linking against. This sort of thing is often justified anyways, think about the global stream objects cin/cout/cerr/clog for example.
Quote:Original post by fpsgamer
think about the global stream objects cin/cout/cerr/clog for example.

Last time I checked, none of those were Singletons... if they were, you'd have to write
cout.getInstance() << "Hello World!\n";
Quote:Original post by fpsgamer
... its an abstract representation of a piece of hardware, plus I have to work with some unfortunate "restrictions" (aka design flaws) of libraries I'm linking against. This sort of thing is often justified anyways, think about the global stream objects cin/cout/cerr/clog for example.

You will find that cin, cout, cerr, and clog are not in the :: namespace but are, in fact, in the std:: namespace. They are certainly not singletons but are in fact namespace-level objects of the class std::basic_istream or std::basic_ostream.

As to your original question, yes, using a private nested namespace is a widely use way to keep your implementation details out of the public API. In addition, many compilers provide a way to force symbols to have nonpublic linkage so that they are not accessible outside of a particular link unit (DSO). That's the default on Windows, and a command-line switch makes it the default on GCC. As a library writer, you;re better off having the default linkage for symbols 'hidden' and then explicitly tag exported symbols (declspec(dllexport)).

Stephen M. Webb
Professional Free Software Developer

The use of an internal "everyone else don't touch this" namespace is fairly common. In boost, the convention is to name this namespace "detail" (e.g. boost::signals::detail), a convention I've adopted in my own code. It's an imperfect but workable substitute for package-level protection.
While the use of a detail namespace is common, it isn't foolproof. You will always have some people who will misuse your implementation details and then claim that your library is buggy. If you gave a better description of your requirements we may be able to point you to a better alternative.
You could expose a C-style interface:

#ifndef SERVICE_H#define SERVICE_Hvoid wibble();void wobble();#endif#include "Service.h"class ServiceProvider {  void wibble();  void wobble();} g_provider;void ServiceProvider::wibble() { /* etc. */ }void wibble() { g_provider.wibble(); }void ServiceProvider::wobble() { /* etc. */ }void wobble() { g_provider.wibble(); }


All translation units can use the interface defined in the header, but needn't even know the class or object exists.

This topic is closed to new replies.

Advertisement