LINUX.ORG.RU

имхо да.. Есть однозначное одношаговое преобразование char const * => string. Поэтому можно, оно будет автоматически применено.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

По шагово, как это все работает, сначала создется обект string из const char * потом возвращается значение, делается return. В этот момент стек еще живой, или уже нет?

anonymous
()
Ответ на: комментарий от dilmah

Постараюсь

A someObject;
string s = someObject.getSomething();

cхематично
string s = return "something";

"something" было создано в стеке, который должен очится
после завершения метода, вопрос в следующем, что раньше
произойдет, присвоение string s = "something", или чистка стека?

anonymous
()

А зачем класс в примере городить было? :)

Выполняться это будет так. У класса string есть конструктор: string::string( const char* ), что по понятиям C++ эквивалентно наличию преобразования типов (const char*)->string, соответственно, в этом случае, оно и будет выполнено вызовом этого конструктора для объекта результата, расположенного на стеке.

Стек в этот момент будет ещё живой, но какое это имеет значение? :)

Rock
()
Ответ на: комментарий от anonymous

> "something" было создано в стеке,

С чего ты взял? something\0 будет размещен в сегменте данных.

anonymous
()
Ответ на: комментарий от anonymous

сам литерал "something" хранится не в стеке. Это статическая память.

Когда внутри функции делается return "something" это эквивалентно return string( "something" );

то есть конструктору string передается указатель на статическую память где лежит строчка something. Он ее копирует внутрь себя. Формально этот вновьобразованный объект string создается на стеке. После этого делается return и так как ты возвращаешь объект а не ссылку то вызывается конструктор копирования с аргументом -- вот этим объектом string. А получатель результата получает результат этого конструктора копирования..

Реально компилятор может соптимизировать и будет одно копирование а не два.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

Спасибо огромное, все мои сомнения развеяны, не смотря на то, что прошляпил что строковые константы выделяются в глобальной куче(а ведь читал Страуструпа :-) )

anonymous
()
Ответ на: комментарий от dilmah

To dilmah
Кстати, а что было бы, если бы возвращал ссылку, все равно он бы
копировал при присваивании...

anonymous
()
Ответ на: комментарий от anonymous

> Кстати, а что было бы, если бы возвращал ссылку

по моему если возвращать ссылку то все может нехило навернуться:)

dilmah ★★★★★
()
Ответ на: комментарий от anonymous

Ламерский совет: никогда (точнее НИКОГДА) не возвращать ссылку|указатель на локальный объект.

anonymous
()
Ответ на: комментарий от anonymous

Имхо не-ламерский совет: _никогда_ не возвращать ссылку/указатель (но ссылка это еще хуже, чем указатель) на поле объекта! Гораздо лучше делать get/set методы.

anonymous
()
Ответ на: комментарий от anonymous

Кто нибуть расстолковать может про возврящение ссылки, чисто академическмий интерес.

anonymous
()
Ответ на: комментарий от anonymous

Возврат ссылки опасен в случае, если объект на которыый ссылка указывает может в один прекрасный момент уничтожиться (вариантов масса - выход за пределы области видимости, delete ...)
Другой пример - ошибка, обнаруживаемая еще на этапе компиляции - если функция принимает аргумент по ссылке, а при вызове в нее передается костантное выражение:
void func(int& arg){
//...
}
//...
func(10);

Еще более замороченный случай: Функция принимает аргумент по ссылке,
а при вызове в нее передается разыменованный нулевой/мусорный указатель - в этом случае компилятор ошибки не замечает, а при вызове получаем сегфолт, о причине которого можно долго думать.

void func(int& i){
int j = i;
}

int* i; func(*i);

ИМХО - здесь то ли недоработка стандарта, то ли компилятора - то идее нужно кидать исключение в момент *i - ан нет: все накернится только когда произойдет реальное обращение к ресурсу.
Например:
void func(int& i){
int j = 10;//... i - не трогаем
}
int *i; func(*i);
Здесь программа отработает без ошибок несмотря на наличие разыменовывания невалидного указателя.

Flogger_d
()
Ответ на: комментарий от anonymous

Ищо более ламерский совет: тщательнее проектировать интерфейсы и не делать открытых полей ни через открытые поля данных, ни через get/set задницу.

anonymous
()
Ответ на: комментарий от Flogger_d

Спасибо Flogger_d, вроде разобрался.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.