You can achieve this, however it comes at some cost:
in C++ you can have internal linkage. Anything inside a unnamed namespace has internal linkage* (see footnote), as well as static free functions (you should prefer the anonymous namespace).
Update: here's the C++11 standard quote from §3.5,4:
An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has
internal linkage. All other namespaces have external linkage. A name having namespace scope that has not
been given internal linkage above has the same linkage as the enclosing namespace if it is the name of
— a variable; or
— a function; or
— a named class (Clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes (7.1.3); or
— a named enumeration (7.2), or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes (7.1.3); or
— an enumerator belonging to an enumeration with linkage; or
— a template.
However, internal linkage applies to translation units, not to static libraries. So if you would use the usual approach putting each class in its own translation unit (=cpp), you could not define them inside anonymous namespaces because you could not link them together to build the library.
You can solve this dilemma by making the whole library one single translation unit: one header providing the library's public interface, one source with the function definitions, and anything else as headers, defined in anonymous namespaces:
mylib.hpp
class MyLib {
public:
int foo();
double bar(int i);
};
mylib.cpp
#include "mylib.hpp"
#include "mylibimpl.h"
int MyLib::foo() {
return fooimpl();
}
double MyLib::bar(int i) {
return BarImpl(i).do();
}
mylibimpl.h
namespace {
inline int fooimpl() { return 42; }
class BarImpl {
double d;
public:
BarImpl(int i) : d(i*3.42) {}
double do() { return 2*d; }
};
}
You'll now have one translation unit (mylib.o
/ mylib.lib
), and all the *impl
classes and functions cannot be seen from outside, because they have internal linkage.
The cost is that you have to reorganize the sources of your internal classes (e.g. to resolve circular dependencies) and that every simple change of the library's internal code will lead to one big recompilation of everything in the lib, just because there is only the single huge translation unit. So you should do this only when the library code itself is very stable or if the library is not too big.
The benefit besides the complete hiding of internal symbols is that the compiler will be able to pull out any optimization it wants, because no implementation details are hidden in different translation units.
*Footnote:
As was commented by Billy ONeal, in C++03 entities in anonymous namespaces have not necessarily internal linkage. However, if they have external linkage, they have names unique to their tranlsation unit and are effectively not accessible from outside that TU, meaning that this procedure works in C++03 as well.