String literals are the objects that are referred to specifically with the syntax
"Hello "
or
"World"
That is what literal means, an atomic syntax for a value. It does not refer to string values in general.
String literals are not temporary objects. They are objects stored in an unspecified way (in practice, often in read-only memory, as you indicated) and have static storage duration, meaning they exist for the duration of the complete program execution.
When you write
string var1 = "Hello ";
you are creating a std::string
object, and this object is initialized from the string literal. It is neither itself a string literal, nor does it hold or refer to one. It will simply copy the characters from the literal into some storage it manages itself. The var1
object (if declared at block scope, ie inside a function) has automatic storage duration, meaning that it lives until the end of the scope in which it was declared.
The line
string var3 = var1 + var2;
used to (prior to C++17) create a temporary std::string
object, which was returned by the +
operator overload of std::string
. Then var3
was move-constructed from this temporary. The temporary resulting from var1 + var2
would then live until the end of the full expression, meaning until after the initialization of var3
was finished.
However, since C++17, there is no temporary involved here anymore. Instead, the +
operator overload will directly construct the var3
object. Before C++17, this was also allowed to happen as so-called return value optimization.
So, in your code, there doesn't exist any "Hello World"
string literal, but there exists exactly one string
object that holds the characters Hello World
, and if you are using a pre-C++17 version, there may be additionally one temporary std::string
object that held the same value, but was destroyed after the initialization of var3
.