I have a doubt regarding private methods & functions. Let's say I have some utility methods that needn't be inside a class. But those same methods need to call other ones that I don't want to expose to the user. For example:
Suspect.h
namespace Suspect {
/**
* \brief This should do this and that and more funny things.
*/
void VerbalKint(void); // This is for you to use
}
Suspect.cpp
namespace Suspect {
namespace Surprise {
/**
* \brief The user doesn't need to be aware of this, as long
* the public available VerbalKint does what it should do.
*/
void KeyserSoze(void) {
// Whatever
}
} // end Surprise
void VerbalKint(void) {
Surprise::KeyserSoze();
}
}
So, this layout works. When including the Suspect.h
, only VerbalKint
is visible.
This can be as well achieved using a class and marking VerbalKint
as static:
class Suspect {
public:
// Whatever
static void VerbalKint(void);
private:
static void KeyserSoze(void);
};
I would like to know if there's any difference between the two approaches. Is one better (faster, easier to maintain) than the other?
What are your thoughts?
An object namespace protects named objects from unauthorized access. Creating a private namespace enables applications and services to build a more secure environment. A process can create a private namespace using the CreatePrivateNamespace function.
Typically, you declare a namespace in a header file. If your function implementations are in a separate file, then qualify the function names, as in this example. A namespace can be declared in multiple blocks in a single file, and in multiple files.
An anonymous namespace makes the enclosed variables, functions, classes, etc. available only inside that file. In your example it's a way to avoid global variables. There is no runtime or compile time performance difference.
A header file is a file that is intended to be included by source files. They typically contain declarations of certain classes and functions. A namespace enables code to categorize identifiers. That is, classes, functions, etc.
If the functions are 'free', you should use an anonymous namespace in the *.cpp
:
namespace Suspect { namespace Surprise { namespace { void KeyserSoze(void) { // Whatever } } // end anon } // end Surprise } // end Suspect
or even:
namespace { void KeyserSoze(void) { // Whatever } } // end anon
This keeps it away from clients so they cannot access, depend on, or collide with your exports when linking. It also keeps unnecessary declarations from them, reducing their compile times and potentially link times or binary sizes if definitions are visible. Finally, it makes it private so they cannot depend on it and you do not need to maintain it for their use. You can still pass these to the outside world, if you choose (function pointer in KeyserSoze()
's case).
At other times, it is preferable to declare a private member function in your class then define it in the *.cpp
(where possible). Typically, you would opt for this approach when you need a closer relationship with the class (e.g. when you need access to some members). You said this was not the case in the question, but I'm just reiterating when private members should be used.
The best approach is to define all helper functions in an unnamed namespace in Suspect.cpp
, instead of in the Suspect::Surprise
namespace.
In your case, this would be:
namespace{ void KeyserSoze(){ ... }; }
You can simply call KeyserSoze
without any namespace specifiers from within Suspect.cpp
.
You can find more information about that here: Unnamed/anonymous namespaces vs. static functions
Another alternative is to declare KeyserSoze
to be static
, but this is not advised by the standard. The C++ Standard reads in section 7.3.1.1 Unnamed namespaces, paragraph 2:
The use of the static keyword is deprecated when declaring objects in a namespace scope, the unnamed-namespace provides a superior alternative
Actually, even though the function is not visible to the eye when you do not declare it in any header; it still is available to the user should they write the declaration.
In C++, the mechanism to hide symbols declared at file level is:
static
for (global) variables and functionsnamespace { ... }
(anonymous namespaces) for anything you wish (more general, more verbose)For example:
// Suspect.cpp
namespace Suspect {
static void KeyserSore() {}
void VerbalKing() { KeyserSore(); }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With