Question

In C++ I would like to define some strings that will be used within a class but the values will be common over all instances. In C I would have used #defines. Here is an attempt at it:

#include <string>
class AskBase {
public:
    AskBase(){}
private:
    static std::string const c_REQ_ROOT = "^Z";
    static std::string const c_REQ_PREVIOUS = "^";
    static std::string const c_REQ_VERSION = "?v";
    static std::string const c_REQ_HELP = "?";
    static std::string const c_HELP_MSG = "  ? - Help\n ?v - Version\n ^^ - Root\n  ^ - Previous\n ^Z - Exit";
};
int main(){AskBase a,b;}

If C++0x is needed that is acceptable.

Was it helpful?

Solution

You will have to define them separately in a single translation unit (source file), like so:

//header
class SomeClass
{
  static const std::string someString;
};

//source
const std::string SomeClass::someString = "value";

I believe the new C++1x standard will fix this, though I'm not entirely sure.

OTHER TIPS

When I need string constants within a class, I never put them in the class itself, but either:

1) If they need to be exposed in the header, I put them outside of the class (in a namespace if appropriate), like this:

const char * const c_REQ_ROOT = "^Z";
...

2) If not, I put them in the cpp file, in an anonymous namespace.

You can then even group strings constant from several related components in the same header file.

It may be not the most "academic" way, but the code is simpler and easier to refactor. I never found any actual advantage of defining string constant as static class members.

I'm really interested by the opinion of other programmers here, so do not hesitate to leave your comments.

I would never use that construction.
If one of the developers refactors the code and starts writing:

   // header
   class StringBug
   {
        static const std::string partOfTheString;
        static const std::string wholeString;
   };

   // source
   const std::string StringBug::partOfTheString = "Begin ";
   const std::string StringBug::wholeString = partOfTheString + "and the rest";

You have a very hard to find bug in the program because there is no garante that partOfTheString is initialized before it is used for the creation of wholeString;

If I want to create class common string I do it like this:

// header
class StringBug
{
    static const std::string& partOfTheString() {
       static const std::string sPartOfTheString("Begin ");
       return sPartOfTheString;      
    }

    static const std::string& wholeString() {
       static const std::string sWholeString( partOfTheString() + "and the rest");
       return sWholeString;
    }
};

According to the Wikipedia article this should be supported in C++0x however I can't find the reference in the State of C++ Evolution page.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top