Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private namespace in source files

Tags:

c++

namespaces

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?

like image 513
Adri C.S. Avatar asked May 29 '13 12:05

Adri C.S.


People also ask

Can a namespace be private?

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.

Should namespaces be in header files?

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.

What is the point of anonymous namespace?

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.

What is the difference between namespace and header file?

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.


3 Answers

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.

like image 60
justin Avatar answered Sep 22 '22 12:09

justin


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

like image 43
Jeff Dun Avatar answered Sep 23 '22 12:09

Jeff Dun


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 functions
  • namespace { ... } (anonymous namespaces) for anything you wish (more general, more verbose)

For example:

// Suspect.cpp

namespace Suspect {

    static void KeyserSore() {}

    void VerbalKing() { KeyserSore(); }

}
like image 21
Matthieu M. Avatar answered Sep 22 '22 12:09

Matthieu M.