37

I am a Java developer and I am pretty new to C++. I need to implement some kind of utility class, and I was thinking of implementing the methods as static. However, I came across to this stackoverflow question about namespace functions vs static method, and apprently namespace functions is preferred approach. So I would like to konw if there is any article or example on how to implement namespace function. E.g, how should I declare namespace functions in header file? Should header only contain function definitions like class header file and implementations should be in cpp file, or should I straight away implement functions in header file?

Basically, I am trying to implement an application to parse a text file that contains some commands. So I am thinking of implementing static helper methods to handle text processing. E.g readCommand(string line). Please let me know if I am in the wrong direction. Thanks

Community
  • 1
  • 1
K Hein
  • 894
  • 2
  • 12
  • 23
  • 1
    C++ draws a pretty sharp distinction between functions and classes. It's not clear from your question which one you're interested in using. – Shep May 08 '12 at 05:10
  • Hi Shep, Thanks for the comment. I added more details to my question. Does it answer your question? – K Hein May 08 '12 at 05:16

3 Answers3

32

how should I declare namespace functions in header file?

namespace MON {
// extern:
t_ret func(const t_param& pValue);
// 'inline':
inline t_ret inline_func(const t_param& pValue) { ... }
} // << MON

Should header only contain function definitions like class header file and implementations should be in cpp file, or should I straight away implement functions in header file?

that depends on whether you want them (potentially) inlined or exported. this often comes down to minimizing dependencies.

to expand on exporting or inlining:

you'd often favor an extern function to minimize dependencies in c++. this is equivalent to separating the definition from the declaration in a class method:

file.hpp

namespace MON {
// extern:
t_ret func(const t_param& pValue);
} // << MON

file.cpp

#include "hefty_stuff.hpp"

MON::t_ret MON::func(const t_param& pValue) { ... }

however, it's at times critical for the definition to be visible in some cases, often for performance or when you know size is important and the header is not included many places. thus, the inline variant is also an option.

an inline function may still be exported, and it may be inlined as requested -- however, any inline function copies may be merged (specifically, the implementation is free to assume all definitions are equal and any copies of the function are unnecessary).

with exported definitions, you may selectively restrict (or quarantine) your include dependencies. that is, #include "hefty_stuff.hpp" need not be in the header to use the functions in file.hpp.


Basically, I am trying to implement an application to parse a text file that contains some commands. So I am thinking of implementing static helper methods to handle text processing.

well, static should be avoided here. c++ uses the one-definition-rule. static will just result in a lot of unnecessary copies. furthermore, an anonymous namespace is the c++ approach to c's static function:

namespace {
t_ret func(const t_param& pValue) { ... }
} // << anon

note: anonymous namespaces may also result in unnecessary copies. the reason you would use them as a substitute for a static function is if you want or need to deviate from the one-definition-rule, and do not want to declare the symbol in a scope which may be 'resolved'.


the final point regards template<> declarations. with templates, the definition must be visible where used, unless your compiler supports extern templates. for templates, you can accomplish definition visibility in multiple ways. typically, people will simply declare the definition in place, or add a header for the definitions which is included either at the end of the header or as needed. with templates, functions do not need to be declared inline to avoid multiple definition errors.

justin
  • 104,054
  • 14
  • 179
  • 226
  • Thanks a lot Justin. Could you explan a bit more on "potentially inlined or exported" point, or point me some article that I should read a bout it? – K Hein May 08 '12 at 05:28
  • @Justin, you forgot to mention about templated functions. – Griwes May 08 '12 at 05:40
  • @Griwes i didn't forget -- it wasn't part of the OP's question. nevertheless, will add a note to the answer. cheers. – justin May 08 '12 at 05:43
  • 2
    @Justin I'd say template functions are relevant, since you don't have the option to put the implementation in a `.cpp`. – juanchopanza May 08 '12 at 05:46
  • @juanchopanza strictly speaking, you have the option to a) put their definitions in cpp files, provided they are visible where needed or b) `#include` the definitions selectively or c) use `extern` templates. – justin May 08 '12 at 06:02
  • @Justin concerning a) and b), isn't there an issue if one attempts to compile the `.cpp` files containing template code implementation? Or is that compiler dependent? – juanchopanza May 08 '12 at 06:07
  • @juanchopanza if not `extern` (opt.c), the definition must be visible where used. it's not typical in smaller projects, but you *can* use these approaches to minimize dependencies and/or restrict visibility to translations where definitions are required. – justin May 08 '12 at 06:23
24

You can declare the functions in the header:

namespace A {
    void foo();
}

and implement in the .cpp:

namespace A {
  void foo() { std::cout << "foo!"; }
}

You can also put the implementation in the header, making sure to declare it inline to avoid breaking the one definition rule:

namespace A {
    inline void foo() { std::cout << "foo()!"; }
}

Note that putting the implementation in the header means that client code has a compilation dependency on the implementation, as well as on headers used for the implementation. In the example above, the client code now depends on the the header, and if we do something trivial like add an exclamation mark to the printout, we need to re-compile, as opposed to re-link, all the client code.

It is very important to put implementations of template functions in the header or in a file included by the header, these cannot go in the .cpp:

namespace B {
  template <class T>
  inline void foo(const T& t) { std::cout << t.name() << "\n"; }
}
sorrymissjackson
  • 2,395
  • 1
  • 19
  • 18
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 1
    +1 for put implementations of template functions in the header. The definition must be visible where used, unless your compiler supports extern templates. – milesma Nov 17 '16 at 00:52
2

how should I declare namespace functions in header file?

namespace YourNamespace
{
    void fun1();
    void fun2();
}

Should header only contain function definitions like class header file and implementations should be in cpp file, or should I straight away implement functions in header file?

If your functions in the namespace are static, you can implement functions in header file, or you must implement in cpp file.