I have a class that has 5 static public functions and 1 static private function (called from one of the public functions). The class doesn't have any member variables. It seems to me that it should be a namespace and not a class. But what to do with the private function? I prefer it not to be accessible by every namespace user, but there is no access control in namespaces.
views:
244answers:
5I don't think there is a solution to this :)
One -different- solution, would be to separate these functions into a separate compilation unit, then declare the private functions inside an anonymous namespace.
Keep the public declaration in the header file. Move the implementations to a cpp file. Mark previously private
methods as static
. This will make them unaccessible from a different linker objects (compilation units) and effectively hide them.
There are two ways i know of
Don't declare them in the header
One way is to not declare those functions inside the header. They can be placed into unnamed namespaces within the implementation file, only.
Indeed, you will then have to implement any function that accesses this private function in the implementation file (not inline in the header).
Put them into a detail namespace
Preferably, you put them in a different header, and include them. So the code of them won't disturb your interface header. This is how boost
does it, too:
#include "detail/destroy.hpp"
namespace orbit {
void destroy() {
detail::destroy_planets();
detail::destroy_stars();
}
}
It seems to me it should be a class, not a namespace. Namespaces in C++ are primarily name resolution tools, and are not intended as the basis for design and do not really provide encapsulation. So I would leave it as it is.
Another solution which, however, does not manage to get completely rid of classes, would be to keep all private functions in some class as static methods, and to have public functions in the namespace. Then allow the public functions to use the class using friend
:
#include <iostream>
// forward declaration of Module::PublicFn()
namespace Module {
void PublicFn();
};
// static class for private functions (methods)
class ModulePrivates
{
private:
// disallow instantiation by making constructor private
ModulePrivates() { }
private:
// example of a private function
static void PrivateFn()
{
std::cout << "ModulePrivates::PrivateFn() called." << std::endl;
}
// allow public function to call PrivateFn()
friend void Module::PublicFn();
};
// namespace for public functions
namespace Module
{
void PublicFn()
{
std::cout << "Module::PublicFn() called." << std::endl;
ModulePrivates::PrivateFn();
}
};
This is clearly only a half-way solution, since you could just as well keep everything in a class (which is what I'd suggest!). Still, you get a namespace with public functions, only there will be one additional class (which however cannot be instantiated and which looks empty from the "outside".)