Professional C__ - Marc Gregoire [248]
const char* ptr = "hello"; // Assign the string literal to a variable.
ptr[1] = 'a'; // BUG! Attempts to write to read-only memory
You can also use a string literal as an initial value for a character array (char[]). In this case, the compiler creates an array that is big enough to hold the string and copies the string to this array. So, the compiler will not put the literal in read-only memory and will not do any literal pooling.
char arr[] = "hello"; // Compiler takes care of creating appropriate sized
// character array arr.
arr[1] = 'a'; // The contents can be modified.
The C++ string Class
As mentioned earlier, C++ provides a much-improved implementation of the concept of a string as part of the Standard Library. In C++, string is a class (actually an instantiation of the basic_string template class) that supports many of the same functionalities as the What Was Wrong with C-Style Strings? To understand the necessity of the C++ string class, consider the advantages and disadvantages of C-style strings. Advantages: They are simple, making use of the underlying basic character type and array structure. They are lightweight, taking up only the memory that they need if used properly. They are low level, so you can easily manipulate and copy them as raw memory. They are well understood by C programmers — why learn something new? Disadvantages: They require incredible efforts to simulate a first-class string data type. They are unforgiving and susceptible to difficult to find memory bugs. They don’t leverage the object-oriented nature of C++. They require knowledge of their underlying representation on the part of the programmer. The preceding lists were carefully constructed to make you think that perhaps there is a better way. As you’ll learn, C++ strings solve all the problems of C strings and render most of the arguments about the advantages of C strings over a first-class data type irrelevant. Using the string Class Even though string is a class, you can almost always treat it as if it were a built-in type. In fact, the more you think of it as a simple type, the better off you are. Programmers generally encounter the least trouble with string when they forget that strings are objects. Through the magic of operator overloading, C++ strings are much easier to use than C strings. For example, two strings can be concatenated by using the + operator: string A("abc"); string B("def"); string C; C = A + B; // C will become "abcdef" The + operator does not try to “add” the values; the + is redefined as meaning “string concatenation.” For example, the following produces 1234, not 46: string A("12"); string B("34"); string C; C = A + B; The += operator is also overloaded to allow you to easily append a string: string A("12"); string B("34"); A += B; // A will become "1234" Another problem with C strings was that you could not use == to compare them. Suppose you have the following two strings: char* a = "12"; char b[] = "12"; Writing a comparison as follows always returned false, because it compared the pointer values, not the contents of the strings: if (a == b) You had to write something as follows: if (strcmp(a, b) == 0) Furthermore, there was no way to use <, <=, >= or > to compare C strings, so strcmp() would return -1, 0 or 1 depending on the lexicographic relationship of the strings. This resulted in very clumsy code, which was also error-prone. With C++ strings, operator==, operator!=, operator<, and so on are all overloaded to work on the actual string characters. Individual characters can still be accessed