views:

67

answers:

4

I've grouped several message strings into a named (non anonymous) namespace in the .cpp file for a class handling output as seen in the code below:

namespace Messages
{
  static const std::string AppTitle = "The Widgetizer - Serving all your Widget needs";
  static const std::string SuccessMsg = "Great success! Widgets for all! ";
  static const std::string FailMsg = "No widgets for you!";
};

void Display::printTitle()
{
  out << Messages::AppTitle << std::endl;
}

void Display::printSuccessMsg()
{
  out << Messages::SuccessMsg << std::endl;
}

void Display::printFailMsg()
{
  out << Messages::FailMsg << std::endl;
}

My logic being that this way they're all in one central location, under a namespace with a meaningful and self-documenting name, and they're not exposed to the client code (as they would be if I had put the namespace in the .h file).

Is this a good practice generally or are there pitfalls to this that I'm not seeing?

Is the static keyword necessary if they're in a file scope namespace like this?

In terms of best practices and accepted C++ idiom & style, would this be better off just as an anonymous namespace? Or simply as static const class members?

I admit it's probably overkill for the small program I'm writing since they'll probably only be used in these functions but generally speaking not hard coding message strings is a good habit no?

+1  A: 

It's okay I guess, you won't lose any points for this. I don't care much for the term "best practice", it is not a common practice. A lot of programs are written with localization in mind, there's several billion potential customers that don't understand a word of English. No standard C++ solution for that, just common practices on your platform. Like string resources.

Hans Passant
Thanks. In terms of common practice, for a large scale, non-trivial program I guess you'd seperate all the localizable text from the code entirely and load it from a file containing the appropriately language at run time? Is that what you mean by string resources?
MTLPhil
It's something of a relief to know there's at least one other person who dislikes the term "best practices".
Jerry Coffin
Yes, you separate it. Into a format that a localization service commonly handles so they won't charge you an arm and a leg. I can't be more detailed like this without you telling us the details.
Hans Passant
I get what you mean. Don't need further details at the moment, thanks. The code I'm working on is a personal project for fun so I'm ok with what I have above, I just wanted to be sure it wasn't something experienced programmers would roll their eyes at. My follow up question was just to get the broad idea of how this would be handled in a professional setting with millions of lines of text to localize.
MTLPhil
Okey dokey. Please don't forget to close your thread by marking the answer.
Hans Passant
A: 

Is this a good practice generally or are there pitfalls to this that I'm not seeing?

It don't seem to be any problem with using namespace to do this.

I often see that putting constant values and global configuration variables in namespace (might they be accessed outside of the definition cpp or not) is a good practice. That way you don't have to create a class just for grouping and you still have the name encapsulation working nice.

Is the static keyword necessary if they're in a file scope namespace like this?

It's not necessary.

In terms of best practices and accepted C++ idiom & style, would this be better off just as an anonymous namespace? Or simply as static const class members?

Static class member would be overkill and non-sense. If you don't need an instance, don't write a class.

Anonymous namespace would be useful only if the code is limited to a specific CPP file.

I admit it's probably overkill for the small program I'm writing since they'll probably only be used in these functions but generally speaking not hard coding message strings is a good habit no?

Following the DRY principle, it looks like you've done well, even for a small program and even if you think your constants will be used only once. Because in the end you never know what the future is made of.

Klaim
A: 

This is okay if you desire the clarity.

My preference would generally be either:

  1. To define file level static variables without the name space (these are always near the top of the file for me).
  2. To define an anonymous namespace and use non-static variables.
  3. Put the definitions in a private part of my subsystem in their own file, complete with header file.

In a particular case that I did use the method you describe it was a mistake. I had fairly large file 3000+ lines with a number of internal classes. In retrospect I should have put my scoped classes into separate files in the internal part of my subsystem.

Generally I prefer 1 or 2 for simple things and 3 for complicated/large things.

Craig W. Wright
A: 

Is this a good practice generally or are there pitfalls to this that I'm not seeing?

Grouping related objects in a namespace is good practice if it makes the code clearer; there aren't any particular pitfalls, but deeply nested namespaces can lead to excessively verbose code if you're not careful.

Is the static keyword necessary if they're in a file scope namespace like this?

You need either static or const to give them internal linkage, but it might be better to enclose your namespace in an unnamed namespace instead. Using static at namespace scope is deprecated, and just using const means you'll get a surprise if someone declares extern objects with the same names.

In terms of best practices and accepted C++ idiom & style, would this be better off just as an anonymous namespace? Or simply as static const class members?

If grouping them in a named namespace makes the code more expressive, then do it; otherwise, don't. I'd prefer not to make them class members unless necessary, to avoid adding unnecessary declarations to the header file.

Mike Seymour
'..but it might be better to enclose your namespace in an unnamed namespace instead'By this you mean make the Messages namespace unnamed right? Not nest the Messages namespace inside another unnmamed namespace?Ideally I'd want to achieve what an unnamed space does, internal linkage, but still have the name so it would be self documenting, so when I use those strings in code, its clear they're all coming from Messages::Messages::AppTitle does seem more expressive to me than simply AppTitle. The namespace gives an idea of what logical unit all these strings are a part of.
MTLPhil
@mtlphil: no, I meant to nest the `Messages` namespace inside an unnamed namespace. That way you can call them `Messages::whatever` if that's what you want, but not clash with objects in other files. This actually gives them external linkage, but makes their fully qualified names inaccessible from other compilation units. This is better than internal linkage, because only objects with external linkage can be template arguments.
Mike Seymour