tags:

views:

5126

answers:

7

I have seen code around with these two styles , I am not not sure if one is better than another (is it just a matter of style)? Do you have any recommendations of why you would choose one over another.

 //Example1
 class Test {

    private:
        static const char* const str;

};

const char* const Test::str = "mystr";

//Example2
class Test {

     private:
         static const std::string str;

};

const std::string Test::str ="mystr";
+3  A: 

Hmmm, a std::string is not the same as a const char *. I usually err on the side of using std::string because it is a class that has many additional capabilities that make it much easier to use.

If performance is paramount and you are using const char * for efficiency, go that way.

Starkii
+2  A: 

The first example requires less overhead for managing the string (i.e., just a pointer to the TEXT section). Also, the second method may require a heap allocation as well to copy the string literal to the std:string class buffer. So, you would end up with two copies of the data.

Judge Maygarden
+1  A: 

The second version has the advantage that it comes with a pre-calculated length and the other benefits of a fleshed out string class. The first has the advantage that the only initialization is just assigning a pointer to static data already loaded in the executable image, where the second one has to initialize the string from that same pointer.

Eclipse
The first version has strlen...
Judge Maygarden
Yes, but it's a O(n) operation, so depending on the usage, that may be an issue.
Eclipse
But I suppose that's just a debate over the benefits of std::string vs char * in general.
Eclipse
+21  A: 

Usually you should prefer std::string over plain char pointers. Here, however, the char pointer initialized with the string literal has a significant benefit.

There are two initializations for static data. The one is called static initialization, and the other is called dynamic initialization. For those objects that are initialized with constant expressions and that are PODs (like pointers), C++ requires that their initialization happens at the very start, before dynamic initialization happens. Initializing such an std::string will be done dynamically.

If you have an object of a class being a static object in some file, and that one needs to access the string during its initialization, you can rely on it being set-up already when you use the const char* const version, while using the std::string version, which isn't initialized statically, you don't know whether the string is already initialized - because the order of initialization of objects across translation unit boundaries is not defined.

Johannes Schaub - litb
+1 I've spent time debugging some very nasty crashes that turned out to be caused by static instances of a string class that broke because of problems with the order of initialisation. Avoid static instances of `std::string` !
the_mandrill
+2  A: 

I tend to favor std::string's over char *'s when doing C++. I prefer std::string mainly for its built in capabilities as well as convenience and safety of not having to deal with pointers.

However, as others have mentioned, the const char * version may be favorable if you are overly concerned about performance. I seem to recall that someone smart once stated that premature optimization is the root of all evil (or some such). :)

goku3989
A: 

In large projects involving several platforms with different compilers and libraries, many teams, and lots of people we have repeatedly run into problems with static std::strings. On some platforms the std:string implementation isn't thread safe. On one platform the compiler optimized code skipped initializing a local std:string form the global static const. After chasing a few of these problems we only allow global static consts for built in types.

maccullt
A: 

First of all, if wouldn't use a char*. If you want an ASCIIZ string, define one of them directly:

const char Test::str[] = "mystr";

For the most part, that's what I'd use. Why waste time and memory for the overhead of string class.

Note that "sizeof(Test::str)" will accurately give you the length of the array, which is the length of the string, including the terminating NUL (strlen(str)+1).

James Curran
Bit weird to state that std::string wastes memory when you waste sizeof(Test::str) by copying a perfectly good const char[] to another const char[].
MSalters
Who's copying anything? Is "const int x = 5;" copying anything? There is just one char[] which intrinsically holds the value "mystr";
James Curran