Первый вопрос
Указатель, возвращаемый std::c_str()
, остается действительным, если строка не изменена.From cppreference.com :
Указатель, полученный из c_str()
, может быть признан недействительным:
- Передача неконстантной ссылки на строкув любую стандартную библиотечную функцию или
- Вызов неконстантных функций-членов в строке, исключая
operator[]
, at()
, front()
, back()
, begin()
, rbegin()
, end()
и rend()
.
В опубликованном вами коде
std::string strTest = "This is a test";
const char* s1 = strTest.c_str();
strTest = "This is b tests"; // This line makes the pointer invalid.
, а затем использование указателя для доступа к строке - неопределенное поведение.
std::cout << s1 << std::endl; // Undefined behavior.
После этого бессмысленно пытаться понять, что делает код.
Второй вопрос
Стандартная библиотека предоставляет функцию перегрузки оператора между std::ostream
и * 1038.* поэтому строки в стиле C могут быть напечатаны разумным способом.Когда вы используете:
std::cout << "Hello, World.";
, вы хотите видеть Hello, World.
в качестве вывода, а не значение указателя, указывающего на эту строку.
По причинам, выходящим за рамки этого ответаперегрузка этой функции реализована как функция, не являющаяся членом.
template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
const CharT* s );
После того, как все связанные с шаблоном токены заменены, эта строка преобразуется в:
std::ostream& operator<<(std::ostream& os, const char* s );
Вы можете увидеть списокфункций перегрузки, не являющихся членами, на cppreference.com .