It is easy to determine what happens by using method size().
For example after creating an object like this
std::string s1 = "";
the size of s1 will be equal to 0.
Here is called constructor
basic_string(const charT* s, const Allocator& a = Allocator());
that copies characters from an array first element of which is pointed to by s. As the length of string literal "" is equal to 0 then the constructed object also does not have elements and its size is equal to 0.
After these statements
s1 += 'a';
s1 += 'b';
the object will contain two characters 'a' and 'b'.
Thus the object will be equal to the object constructed like std::string( "ab" );
.
Take into account for example if you have a character array defined like
char s[] = { 'a', 'b', '\0', 'c', 'd', '\0' };
and will use to construct an object of type std::string like this
std::string s1( s );
then s1 will contain only two elements 'a' and 'b' and its size will be equal to 2.
It will be useful to consider another example. Let's assume that you wrote
std::string s1 = "";
and then
s1 += 'a';
s1 += 'b';
s1 += '\0';
In this case s1 will not be equal to object std::string( "ab" )
because the size of s1 is now equal to 3.
Another interesting example. You can use constructor
basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
It is similar to the previous constructor except it allows to specify explicitly the number of characters in the character array pointed to by pointer s that will be used to construct an object of type std::string.
In this case if you will write
std::string s1( "ab", 3 );
std::cout << s1.size() << std::endl;
if ( s1 == std::string( "ab" ) ) std::cout << "They are equal" << std::endl;
else std::cout << "They are not equal" << std::endl;
then the output will be
3
They are not equal
At the same time if you will write
std::cout << s1 << std::endl;
you will see
ab