I sit around and think about whether or not I should be using const char*
or const std::string&
pretty often when I'm designing class interfaces and when it comes down to it, I often feel like there's 6 in one hand with half a dozen in the other.
Take the following two function prototypes:
void foo(const char* str); void foo(std::string str);
If the foo
function were to store a string, I would say the second is a better option due to the ability to pass a string and utilize move semantics where possible. However, if foo
only needed to read the string, would the const char*
solution be better?
On a performance perspective, a temporary std::string
wouldn't need to be created. However, calling the function with an already existing string as an argument looks obtrusive: foo(mystr.c_str())
. Worse yet, if more advanced operations need to be done on the array at some point down the road or if a copy should be stored, the interface then has to change.
So my questions is this:
Are there well defined, either personal or otherwise, conventions that rule when std::string
or const char*
is a better choice? Furthermore, when starting a new project, is it best to be consistent with usage or just take whichever one fits the current chunk of code best?
In C++ you should in almost all cases use std::string instead of a raw char array. std::string manages the underlying memory for you, which is by itself a good enough reason to prefer it.
Use std::string when you need to store a value. Use const char * when you want maximum flexibility, as almost everything can be easily converted to or from one.
std::string class in C++ C++ has in its definition a way to represent a sequence of characters as an object of the class. This class is called std:: string. String class stores the characters as a sequence of bytes with the functionality of allowing access to the single-byte character.
So the character array approach remains significantly faster although less so. In these tests, it was about 29% faster.
const char*
is a throwback to C. I'd say that in decent C++, about the only use for it is in extern "C"
APIs.
std::string
has a number of advantages:
It provides a constant-time size()
function. Discovering the length of a const char*
takes linear time.
It is guaranteed to be valid. A const char*
has to be checked for being null, and it is entirely possible to pass incorrect data - data missing a null terminator. Such an occurrence is pretty much guaranteed to result in a crash or worse.
It is compatible with standard algorithms.
If you're worried about performance impacts of having to create a std::string
to call the function, consider taking the approach the standard library uses - change the function to take a pair of iterators instead. You can then provide a convenience overload taking a const std::string&
delegating to the iterator-pair one.
Just a few notes from personal experience. If you are working on a c++ project (as per the tag you added) stick to the std::string
provided as much as you can. Do not try to reinvent the most basic of all structures, the almighty string. I saw several projects where they reinvented the basic string and afterwards spent months fine tuning it.
In case of your c++ project from the moment you have introduced a char*
variable you fall back to standard C functions, such as strlen()
and strcpy
(just to name two ...). And from this point your project starts turning in a mess, with hand managed memory allocation, etc...
In case you need to interact with third party libraries which accept const char*
as their parameter (and I suppose you trust those libraries - ie: you trust they do not const_cast
away the constness to do evil things with your poor string) you can use std::string::c_str()
to get the const char*
out of your string.
In case you need to interact with libraries which have methods accepting char*
I highly recommend you take a copy of your string's c_str()
and use that as the ingoing parameter to the library (of course, do not forget to delete the extra copy).
Beside of these extra points I just subscribe to all three points from Angew's response.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With