In the class below is there any benefit or reason why speak()
returns a const char*
instead of a std::string
?
class Animal
{
protected:
std::string m_name;
Animal(std::string name)
: m_name(name)
{
}
public:
std::string getName() { return m_name; }
const char* speak() { return "???"; }
};
What a string literal such as "???"
does is it tells the compiler to include a piece of global memory containing that particular sequence of characters (plus the character '\0'
at the end). The string literal expression has a value of type const char*
pointing to that piece of global memory.
What that means is that in this very particular circumstance, it's safe to pass around the pointer. Note that the following function
std::string speak() { return "???"; }
has the same function body but a rather different code path. The string literal expression (the global memory, the pointer) is still there, but it is used as an argument to the constructor for std::string
; it is implicitly converted to std::string
.
That constructor for std::string
dynamically allocates some memory (well not in this case with the short string optimization, probably) and copies from the pointer you give it.
So in this very particular case, where you have a string literal and nothing else, you can return a const char*
. It will probably get implicitly converted to std::string
when passed to another function which expects it, so const char*
isn't all that much of an optimization.
std::string
comes with a lot of maybe unwanted and also unused features. If you do not want all that features you should think about the cost of the usage. Passing around std::string
needs at minimum a first copy from the literal to the internal storage of the string. Maybe you get some additional copies if you pass the string to other functions and back. If small string optimization is present, you can not simply move the string, so the cost becomes higher in that case.
If you do not want the cost but get all features for a constant string, you should take a look for std::string_view
. The implementation typically contains only a pointer to the underlying data and a value for size. So it comes with less cost and is very feature rich.
And indeed there is nothing wrong with passing const char*
if it fits to your needs.
Use always std::string
for constant strings is a very common pattern but not a good one.
In addition to the other answers, returning a const char*
may be needed if you need to call your functions from a different library that is written in a different C++ compiler. For example your Animal
class may be compiled with Visual Studio 2013, but the library where you use the Animal
class from may be compiled with Visual Studio 2015.
For more info: How do I safely pass objects, especially STL objects, to and from a DLL?
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