Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ when to return a const char* instead of a std:string

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 "???"; }
};
like image 410
arcoxia tom Avatar asked Apr 24 '18 09:04

arcoxia tom


3 Answers

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.

like image 158
hegel5000 Avatar answered Sep 22 '22 12:09

hegel5000


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.

like image 35
Klaus Avatar answered Sep 22 '22 12:09

Klaus


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?

like image 35
Kakalokia Avatar answered Sep 22 '22 12:09

Kakalokia