Почему нет std::string::operator const char*()
От: Brother Россия  
Дата: 30.11.01 05:50
Оценка:
Речь идет о методах std::string...
Вот цитата из Страуструпа:
"Преобразование в С-строку может быть обеспечено оператором operator const char*(), а не c_str(). Это обеспечило бы удобство неявного преобразования, но ценой всякого рода сюрпризов в тех случаях, когда такого преобразования не ожидалось."
Угу, понятно — неявные преобразования на то и неявные, чтобы иногда происходить неожиданно и неявно :) Из-за чего с ними нужно проявлять внимательность, это понятно. В std::string не включен оператор неявного пеобразования в const char*, вместо этого — const char* c_str() const;
Внимание, вопрос!
Какой хороший (простой и очевидный) пример показал бы глубину грехопадения тех, кто склонен считать, что std::string::operator const char*() — это хорошо :)
С уважением,
Сергей
Re: Почему нет std::string::operator const char*()
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 30.11.01 06:11
Оценка: 4 (1)
Здравствуйте Brother, Вы писали:

B>Внимание, вопрос!

B>Какой хороший (простой и очевидный) пример показал бы глубину грехопадения тех, кто склонен считать, что std::string::operator const char*() — это хорошо

П.Халперн."Стандартная библиотека С++ на примерах":

Весь вопрос в том, кто потом будет освобождать память.

вариант 1. Мы сами, ручками. Смотрим что из этого получится:

extern void f(const char*);
std:string s("hello world");
f(s); // f() принимает временный, неименованый указатель - > мы не сможем освободить память по этому адресу


вариант 2. Память будет очищать сам string

extern void f(const char*);
extern std:string g();
const char* p = g(); // !! std:string возвращаемый g() 
                     // сохраняется во временной переменной string
f(p); // большой облом ! после выхода за строку 3 
      // временная переменная string уничтожается 
      // и очищает память, на которую указывает p. 
      // Что же мы передали в f()?
Re[2]: Почему нет std::string::operator const char*()
От: retalik www.airbandits.com/
Дата: 30.11.01 06:36
Оценка:
Здравствуйте Odi$$ey, Вы писали:

O$>Весь вопрос в том, кто потом будет освобождать память.

{skip}

А что кардинально изменится, если в этих двух примерах явно написать c_str()?

По-моему, зря они не включили этот оператор. Как будто в c++ мало других мест (даже в STL), где можно совершить ошибку (перепутать begin() и end(), например).
Успехов,
Виталий.
Re[3]: Почему нет std::string::operator const char*()
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 30.11.01 06:50
Оценка:
Здравствуйте retalik, Вы писали:

R>Здравствуйте Odi$$ey, Вы писали:


O$>>Весь вопрос в том, кто потом будет освобождать память.

R>{skip}


R>А что кардинально изменится, если в этих двух примерах явно написать c_str()?


в смысле результата — ничего. В смысле анализа кода на предмет того, а что же собственно происходит — коду добавится прозрачности, все-так неявное преобразование оно и есть неявное, и если текста не три строки, как в примере, то пялиться в него можно было бы довольно долго.

R>По-моему, зря они не включили этот оператор. Как будто в c++ мало других мест (даже в STL), где можно совершить ошибку (перепутать begin() и end(), например).


ну этож не причина добавить таких мест еще и побольше, побольше
Re[2]: Почему нет std::string::operator const char*()
От: Stanislav V. Zudin Россия  
Дата: 30.11.01 07:15
Оценка:
Здравствуйте Odi$$ey, Вы писали:

O$>Весь вопрос в том, кто потом будет освобождать память.
O$>вариант 1. Мы сами, ручками. Смотрим что из этого получится:
Что-то тут не так...
O$>extern void f(const char*);
O$>std:string s("hello world");
O$>f(s); // f() принимает временный, неименованый указатель - > мы не сможем освободить память по этому адресу


А с какой мы должны освобождать память? Память освободится в деструкторе std:string s. Или я чего-то не понимаю?

O$>extern void f(const char*);
O$>extern std:string g();
O$>const char* p = g(); // !! std:string возвращаемый g() 
O$>                     // сохраняется во временной переменной string
O$>f(p); // большой облом ! после выхода за строку 3 
O$>      // временная переменная string уничтожается 
O$>      // и очищает память, на которую указывает p. 
O$>      // Что же мы передали в f()?


строка, возвращаемая g() с равной вероятностью может умереть как до вызова f(p), так и после — это как уж разработчикам компилятора захочется.
Показан пример как не надо программировать.


Есть у меня эта "Стандартная библиотека С++ на примерах". Не в восторге. Плохой перевод, примитивные примеры. Полезность книги — нулевая :-(

Касательно первоначального вопроса пример могу привести такой:
std::string s("bla-bla-bla");
s += '\0';
s += "one more string";
std::cout << s;


С std::string::operator const char*() было бы не ясно — что выводить — то ли С-шную строку до символа '\0', то ли С++-ную целиком.
_____________________
С уважением,
Stanislav V. Zudin
Re[3]: Почему нет std::string::operator const char*()
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 30.11.01 07:28
Оценка:
Здравствуйте Stanislav V. Zudin, Вы писали:

SVZ>А с какой мы должны освобождать память? Память освободится в деструкторе std:string s. Или я чего-то не понимаю?


если у нас одна и таже область памяти используется и через std:string и через const char* p, то в принципе возможны два варианта освобождения этой памяти, вот эти два варианта и рассмотрены.

SVZ>строка, возвращаемая g() с равной вероятностью может умереть как до вызова f(p), так и после — это как уж разработчикам компилятора захочется.


это сути дела не меняет, только усугубляет, прошу прощения за тавтологию

SVZ>Показан пример как не надо программировать.


а никто и не просил пример хорошего стиля

SVZ>Есть у меня эта "Стандартная библиотека С++ на примерах". Не в восторге. Плохой перевод, примитивные примеры. Полезность книги — нулевая


не согласен, но не важно. А какая есть хорошая книга по STL на русском?
Re[4]: Почему нет std::string::operator const char*()
От: Аноним  
Дата: 30.11.01 07:43
Оценка:
Здравствуйте Odi$$ey, Вы писали:

O$>не согласен, но не важно. А какая есть хорошая книга по STL на русском?
Увы, других книг по STLю вообще не видел. Ни на русском, ни на аглицком. :( Стандарт и Страуструп не считаются.
Re[3]: Почему нет std::string::operator const char*()
От: Андрей Тарасевич Беларусь  
Дата: 30.11.01 08:08
Оценка: 9 (3)
Здравствуйте retalik, Вы писали:

R>Здравствуйте Odi$$ey, Вы писали:


O$>>Весь вопрос в том, кто потом будет освобождать память.

R>{skip}


R>А что кардинально изменится, если в этих двух примерах явно написать c_str()?


Изменится то, что тебе придется явно написать вызов этого метода. Явный вызов метода означает, что ты отдаешь себе отчет в том, что делаешь. Оператор приведения типа имеет свойство вызываться компиляторм неявно, что может привести к его вызову в ситуациях, когда ты этого не хотел и не ожидал. Логика тут примерно та же, что и в ключевом слове 'explicit' при объявлении конверсионного конструктора — подавить потенциално опасные неявные действия.

Еще одна причина, по которой 'c_str' не сделана в виде оператора приведения типа, заключается в том, что за этим методом может скрываться нетривиальная операция. Объекты класса 'std::string' хранят последовательности, которые в общем случае не являются null-теминаторными. Длина хранимой последовательности хранится отдельно и наличие терминаторного символа на конце хранимой поледовательности не требуется. (Более того, хранимая последовательность может содержать символы, которые ты считаешь терминаторными, в середине.) Это означает, что вызов метода 'c_str' в общем случае может выливаться в нетривиальную операцию, заключающуюся в копировании хранимой последовательности в новый буфер и с добавлением null-терминатора в конце. Например, стандарт языка говорит, что вызов 'c_str' инвалилирует все указатели, ссылки и итераторы, связанные с хранимой в 'std::string' последовательностью. Я думаю, многие согласятся, что использовать любые потенциально тяжелые действия в реализации оператора приведения типа — не самая лучшая идея, все по той самой причине, что оператор приведения типа вызывается неявно.

Многие реализации, конечно, будут "заранее" хранить последовательность в null-терминаторном виде и реализация 'c_str' в них будет тривиальной. Но стандартом языка этого не требуется.
Best regards,
Андрей Тарасевич
Re[5]: Почему нет std::string::operator const char*()
От: Юнусов Булат Россия  
Дата: 30.11.01 08:15
Оценка:
Здравствуйте Аноним, Вы писали:

А>Здравствуйте Odi$$ey, Вы писали:


O$>>не согласен, но не важно. А какая есть хорошая книга по STL на русском?
А>Увы, других книг по STLю вообще не видел. Ни на русском, ни на аглицком. Стандарт и Страуструп не считаются.
А Леен Аммераль? На русском, и стиль писания книг и кода у него явно поменялся со времен его четырехтомника по графике, так что его книгу по STL читать одно удовольствие.
Re[6]: Почему нет std::string::operator const char*()
От: Stanislav V. Zudin Россия  
Дата: 30.11.01 08:34
Оценка:
Здравствуйте Юнусов Булат, Вы писали:

ЮБ>А Леен Аммераль? На русском, и стиль писания книг и кода у него явно поменялся со времен его четырехтомника по графике, так что его книгу по STL читать одно удовольствие.

А поподробнее? Как называется, где и когда издана?
_____________________
С уважением,
Stanislav V. Zudin
Re[7]: Почему нет std::string::operator const char*()
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 30.11.01 09:18
Оценка:
Здравствуйте Stanislav V. Zudin, Вы писали:

SVZ>Здравствуйте Юнусов Булат, Вы писали:


ЮБ>>А Леен Аммераль? На русском, и стиль писания книг и кода у него явно поменялся со времен его четырехтомника по графике, так что его книгу по STL читать одно удовольствие.

SVZ>А поподробнее? Как называется, где и когда издана?

Леен Аммерааль "STL для программистов на С++" ДМК, Москва, 1999

http://www.dore.ru/shop/full_book_info.pl/id/135
Re[4]: Почему нет std::string::operator const char*()
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.01.02 22:33
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

В нашем ascSrting сделано именно так как говорил retalik и что характерно ни одной проблемы за 3 года.

Проблема явно высосана из пальца. Мы при работе всегда подразумеваем, что памятью может управлять только хелпер... и никаких проблем. А общая логика работы похожа на работу с указателями на COM-интерфейс.

Работать же на порядок проще.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Почему нет std::string::operator const char*()
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 08.01.02 05:38
Оценка:
Здравствуйте VladD2, Вы писали:

VD>Проблема явно высосана из пальца. Мы при работе всегда подразумеваем, что памятью может управлять только хелпер... и никаких проблем.


однако, сколько человек, кроме разаработчиков применяют ascString? как там говорил лучший друг советских детей — "нет человека, нет и проблемы" ?
Re[5]: Почему нет std::string::operator const char*()
От: Brother Россия  
Дата: 08.01.02 05:44
Оценка: 6 (1)
Здравствуйте VladD2, Вы писали:

VD>В нашем ascSrting сделано именно так как говорил retalik и что характерно ни одной проблемы за 3 года.

Это хорошо. Пожелаем всем нам хорошего кода!

VD>Проблема явно высосана из пальца. Мы при работе всегда подразумеваем, что памятью может управлять только хелпер... и никаких проблем. А общая логика работы похожа на работу с указателями на COM-интерфейс.

Да, наверное, не так страшен черт. Хотя и в комитете по стандартизации тоже не дураки сидят
Пока шла дискуссия, вот какой пример ошибки (взят почти из жизни) я нашел в оправдание Страуструпа со товарищи
LPCTSTR GetString() 
{ 
   CString str = "The stuff that sucks"; 
   return str; 
}

На первый взгляд "все чинно-блааронно", но при внимательном рассмотрении все становится на свои места — str является локальной переменной, при возвращении return str; экземпляр CString неявно приводится к указателю на строку (на внутренний буфер!) и тут же уничтожается, буфер освобождается, и по возвращении из функции имеем в руках указатель на занятую кем-то другим память. Грустно.
Естественно, если думать, что пишешь то такие ошибки не возникают, однако источник ошибок, по-моему, все же существует.
Ваше мнение?
С уважением,
Сергей
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.