If you just want to pass a std::string
to a function that needs const char*
you can use
std::string str;
const char * c = str.c_str();
If you want to get a writable copy, like char *
, you can do that with this:
std::string str;
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0
// don't forget to free the string after finished using it
delete[] writable;
Edit: Notice that the above is not exception safe. If anything between the new
call and the delete
call throws, you will leak memory, as nothing will call delete
for you automatically. There are two immediate ways to solve this.
boost::scoped_array
boost::scoped_array
will delete the memory for you upon going out of scope:
std::string str;
boost::scoped_array<char> writable(new char[str.size() + 1]);
std::copy(str.begin(), str.end(), writable.get());
writable[str.size()] = '\0'; // don't forget the terminating 0
// get the char* using writable.get()
// memory is automatically freed if the smart pointer goes
// out of scope
std::vector
This is the standard way (does not require any external library). You use std::vector
, which completely manages the memory for you.
std::string str;
std::vector<char> writable(str.begin(), str.end());
writable.push_back('\0');
// get the char* using &writable[0] or &*writable.begin()
Consider this:
std::string str = "Hello " + "world"; // bad!
Both the rhs and the lhs for operator +
are char*
s. There is no definition of operator +
that takes two char*
s (in fact, the language doesn't permit you to write one). As a result, on my compiler this produces a "cannot add two pointers" error (yours apparently phrases things in terms of arrays, but it's the same problem).
Now consider this:
std::string str = "Hello " + std::string("world"); // ok
There is a definition of operator +
that takes a const char*
as the lhs and a std::string
as the rhs, so now everyone is happy.
You can extend this to as long a concatenation chain as you like. It can get messy, though. For example:
std::string str = "Hello " + "there " + std::string("world"); // no good!
This doesn't work because you are trying to +
two char*
s before the lhs has been converted to std::string
. But this is fine:
std::string str = std::string("Hello ") + "there " + "world"; // ok
Because once you've converted to std::string
, you can +
as many additional char*
s as you want.
If that's still confusing, it may help to add some brackets to highlight the associativity rules and then replace the variable names with their types:
((std::string("Hello ") + "there ") + "world");
((string + char*) + char*)
The first step is to call string operator+(string, char*)
, which is defined in the standard library. Replacing those two operands with their result gives:
((string) + char*)
Which is exactly what we just did, and which is still legal. But try the same thing with:
((char* + char*) + string)
And you're stuck, because the first operation tries to add two char*
s.
Moral of the story: If you want to be sure a concatenation chain will work, just make sure one of the first two arguments is explicitly of type std::string
.
Best Answer
You probably don't want to use a pointer to your
String
class. Try this code:When defining new operators for C++ types, you generally will work with the actual type directly, and not a pointer to your type. C++ objects allocated like the above (as
String testing
) are allocated on the stack (lives until the end of the "scope" or function) instead of the heap (lives until the end of your program).If you really want to use pointers to your type, you would modify the last line like this:
However, following the example of
std::string
this is not how you would normally want to use such a string class.