Sign in to follow this  
fpsgamer

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

Recommended Posts

fpsgamer    856
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?

Share this post


Link to post
Share on other sites
Hodgman    51336
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;
}
...

Share this post


Link to post
Share on other sites
fpsgamer    856
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.

Share this post


Link to post
Share on other sites
fpsgamer    856
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.

Share this post


Link to post
Share on other sites
DevFred    840
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";

Share this post


Link to post
Share on other sites
Bregma    9214
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)).

Share this post


Link to post
Share on other sites
Sneftel    1788
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.

Share this post


Link to post
Share on other sites
Zahlman    1682
You could expose a C-style interface:


#ifndef SERVICE_H
#define SERVICE_H
void 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.

Share this post


Link to post
Share on other sites
mrbastard    1577
Quote:
Original post by fpsgamer
... are there any generic singleton classes that I can use? I've searched boost already.


Loki provides a customisable singleton.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this