Skip to main content
gamedev.net
🔒 Locked

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

Started by fpsgamer 9 replies 7.5k views
Original Post
fpsgamer
fpsgamer
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?
Hodgman
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.
#include "myHeader.h"using namespace MyLibrary;namespace//anonymous{  GlobalObject g_Object;}...
fpsgamer
fpsgamer
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.
thedustbustr
thedustbustr
you could always change your design. /snippy comment
fpsgamer
fpsgamer
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.
DevFred
DevFred
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";
Bregma
Bregma
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
Sneftel
Sneftel
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.
Zahlman
Zahlman
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.
mrbastard
mrbastard
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.
[size="1"]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.