powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Объясните раз и навсегда про возвращение из функции указателя и ссылки
45 сообщений из 45, показаны все 2 страниц
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38015993
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Допустим, есть какая-то функция.Предполагается, что поток только один.

1)Может ли она возвращать указатель на объект, созданный внутри неё?
2)Меняет ли что-то, если объект статический, создан внутри ф-и?

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

На вопрос 2) я бы ответил, что возвращать ссылку на статический объект, определённый внутри ф-и можно во всех случаях, только надо следить, чтобы всё корректно работало. А что с 1) ?
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38015994
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если объект создан динамически (в куче), то можно, если на стеке, то нельзя
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016015
Фотография vromanov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть облась жизни, есть облась видимости. Тут надо проверять область жизни.
Все созданное на стеке живет только до выхода из функции.
Созданное в динамической памяти, в пулах живет пока не будет освобождено. Поэтому возвращать можно. Если памать, кончено, не освобождается внутри функции.
Статические пременные живут вечно. Так что указатели на них также можно возвращать. Для однопоточных приложений вполне толковый механизм.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016033
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cerebrum и vromanov,

Правильно ли я понял, что все Ваши ответы следует понимать следующим образом:
При возвращении константного/неконстантного указателя/ссылки на статический объект, определённый внутри функции, всё будет работать нормально, если всё правильно записать?
При возвращении константного/неконстантного указателя/ссылки на нестатический объект надо, чтобы нестатический объект создавался в куче?
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016073
Фотография vromanov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvango,

Да
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016078
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, кажется, разобрался.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016092
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А Вы пишите, что если объект не является статическим, он должен создаваться в куче. Но вот пример

...
std::string f(){ return "abc"; }
...
const std::string& s = f();
...

Здесь всё нормально, а объект не является статическим. Как это объяснить? И почему то же самое не верно для указателей?

const std::string* const ps = f(); -- почему не хочет компилироваться (компилится лишь при использовании new для выделения памяти)?
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016100
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoА Вы пишите, что если объект не является статическим, он должен создаваться в куче. Но вот пример

...
std::string f(){ return "abc"; }
...
const std::string& s = f();
...

Здесь всё нормально, а объект не является статическим. Как это объяснить? И почему то же самое не верно для указателей?

const std::string* const ps = f(); -- почему не хочет компилироваться (компилится лишь при использовании new для выделения памяти)?
В первом случае, когда функция производит возврат, создается копия возвращаемого объекта

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
int Add(int a, int b)
{
	int result = a + b;
	return result; 
}

// создается временная копия result, которая при помощи механизмов языка,
// существует ровно столько сколько необходимо для передачи ее значения
// внешней переменной
int nC = Add(231, 36); // адрес nC != адресу result, но содержимое одинаково (конструктор копирования)

// если такой переменной нет, копия сразу же разрушается
Add(231, 36); // result после return не существует, он никому (кроме отладчика) НЕ нужен!



В случае указателя

Код: plaintext
1.
2.
3.
4.
5.
int* Add(int a, int b)
{
	int result = a+b;
	return &result;
}


Память по которой расположен result жива пока выполняется функция Add. Как только произошел возврат из Add все переменные созданные на стеке в функции Add разрушаются, а значит адрес result, теперь указывает на какой-то абстрактный мусор.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016104
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо,

если я правильно понял, то в случае с ссылкой на константу передаётся копия созданного объекта, а внутренний объект разрушен, но всё равно всё работает, передаётся-то объект, а не обломки,

а в случае с константным указателем на кностанту передаются обломки (указатель на разрушенный объект), потому всё и отказывается компилироваться.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016218
Abstraction
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoСпасибо,

если я правильно понял, то в случае с ссылкой на константу передаётся копия созданного объекта, а внутренний объект разрушен, но всё равно всё работает, передаётся-то объект, а не обломки,

а в случае с константным указателем на кностанту передаются обломки (указатель на разрушенный объект), потому всё и отказывается компилироваться.Нет. Если писать так:
Код: plaintext
1.
2.
3.
4.
5.
int& Add(int a, int b)
{
	int result = a+b;
	return result;
}

, то тоже получится фигня. Смотрите на то, что возвращает функция, а не на то, чему это возвращаемое значение присваивается.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016320
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoДопустим, есть какая-то функция. Предполагается, что поток только один.

1)Может ли она возвращать указатель на объект, созданный внутри неё?


Да.

ayvango2)Меняет ли что-то, если объект статический, создан внутри ф-и?


Т.е. может ли функция вернуть указатель на статический объект, область видимости которого -- эта функция ?
Да, может.
Вообще, функция в С++, которая возвращает по своей сигнатуре указатель какого-то типа, может возвращать
любое валидное выражение типа "указатель на этот тип", С++ никак не ограничивает функцию ни в чём.
Другое дело, что по семантике например бессмысленно возвращать указатель на автоматический объект, созданный
в этой функции -- он будет удалён по выходу из этой функции, и указатель автоматом станет невалидным.


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


Ничем в общем не отличается от возврата указателя. Любое валидное выражение этого типа может быть возвращено.
Но это не значит, что это имеет всегда смысл.

Это я к тому, что возможно ты неправильно сформулировал вопрос. Лучше было бы, если бы ты привёл все интересующие тебя варианты кода, тогда можно было бы их прокомментировать и сказать, где имеет смысл так делать, а где нет.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016323
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CerebrumЕсли объект создан динамически (в куче), то можно, если на стеке, то нельзя

Что значит нельзя ? Можно, но просто он уже станет невалидным.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016328
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoА Вы пишите, что если объект не является статическим, он должен создаваться в куче. Но вот пример

...
std::string f(){ return "abc"; }
...
const std::string& s = f();
...

Здесь всё нормально, а объект не является статическим. Как это объяснить?


Ну здесь -то нет указателей, здесь объект по значению возвращается.
Им инициализируется константная ссылка, это по стандарту продлевает жизнь временного объекта на время
жизни этой ссылки.

ayvango И почему то же самое не верно для указателей?
const std::string* const ps = f(); -- почему не хочет компилироваться (компилится лишь при использовании new для выделения памяти)?

Не хочет компилироваться -- потому что ты указатель инициализируешь объектом, а не его адресом.

Это если функция f выглядит как

std::string f(){ return "abc"; }

если же как

std::string* f(){ return new std::string("abc"); }

то проблема в том, что указатель НЕ продлевает время жизни объекта, в отличие от ссылки.
Но собвтсенно и объект-то не возвращается, возвращается указатель на него.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016332
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoСпасибо,

если я правильно понял, то в случае с ссылкой на константу передаётся копия созданного объекта, а внутренний объект разрушен, но всё равно всё работает, передаётся-то объект, а не обломки,

а в случае с константным указателем на кностанту передаются обломки (указатель на разрушенный объект), потому всё и отказывается компилироваться.

Понял ты неправильно. Ссылка или указатель -- всё равно. Важно, что функция возвращает.
Если ссылку или указатель, это не влияет на время жизни объекта, которым они проинициализированы
при возврате. Если значение -- то значение и возвращается, при этом объект копируется.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016344
AbstractionayvangoСпасибо,

если я правильно понял, то в случае с ссылкой на константу передаётся копия созданного объекта, а внутренний объект разрушен, но всё равно всё работает, передаётся-то объект, а не обломки,

а в случае с константным указателем на кностанту передаются обломки (указатель на разрушенный объект), потому всё и отказывается компилироваться.Нет. Если писать так:
Код: plaintext
1.
2.
3.
4.
5.
int& Add(int a, int b)
{
	int result = a+b;
	return result;
}

, то тоже получится фигня. Смотрите на то, что возвращает функция, а не на то, чему это возвращаемое значение присваивается.

А так работает?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int& Add(int a, int b)
{
	int result = a+b;
	return result;
}

int main() {
 int &res = Add(1, 2);
 std::cout << res;
}
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38016472
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivЛучше было бы, если бы ты привёл все интересующие тебя варианты кода, тогда можно было бы их прокомментировать и сказать, где имеет смысл так делать, а где нет.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
class Example
{
   int i;
   std::string s;
public:
   Example(int j) : i(j), s("abc"){};
};


const Example& f1(){ return Example(1); }
Example& f2(){ return Example(2); }
const Example* f3(){ return new Example(3); }
Example* f4(){ return new Example(4); }


int main(){
   const Example& e1 = f1();
   Example& e2 = f2();
   const Example* e3 = f3();
   Example* e4 = f4();

   delete e3;
   delete e4;
}



в VisualStudio всё копмилируется, только вот для f1() и f2() стоят предупреждения о возвращении ссылки на локальную переменную. Вопрос в том, будет ли это корректно работать?
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017368
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoв VisualStudio всё копмилируется, только вот для f1() и f2() стоят предупреждения о возвращении ссылки на локальную переменную. Вопрос в том, будет ли это корректно работать?Нет, не будет.
Добавь в свой класс деструктор с printf/cout, добавь после каждой команды в своем примере печать строк "сделано это" и посмотри когда именно вызываются деструкторы.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017582
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
посмотри когда именно вызываются деструкторы
Деструкторы для e1 и e2 вызываются почти сразу же, причём сначала вызывается деструктор для e1, затем для e2. Означает ли это, что при выходе из ф-и f1() и f2() соответственно соответствующие объекты уничтожаются несмотря на то, что на них указывает ссылка? Почему ссылка не продлевает время жизни объекта? И почему для встроенных типов (int) случаи со ссылками работают?
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017736
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoпосмотри когда именно вызываются деструкторы
Деструкторы для e1 и e2 вызываются почти сразу же, причём сначала вызывается деструктор для e1, затем для e2. Означает ли это, что при выходе из ф-и f1() и f2() соответственно соответствующие объекты уничтожаютсяДа.
ayvango несмотря на то, что на них указывает ссылка?Ссылки и указатели никак не влияют на время жизни объектов.
ayvangoИ почему для встроенных типов (int) случаи со ссылками работают?А они не работают. Ссылка на уничтоженный int продолжает существовать и до тех пор пока никому не понадобилось место где раньше был записан этот int в той ячейке памяти будет записано старое значение. И его даже можно будет использовать.... Но как только другая функция потребует память - твоя ссылка начнет показывать на память занятую совсем другим значением.
У элементарных типов нету деструкторов поэтому ты просто не видишь когда они уничтожаются, но на самом деле правила уничтожения и у объектов и у элементарных типов одинаковые.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017753
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А вот тут тогда почему всё работает?

http://alenacpp.blogspot.ru/2008/01/const.html
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017784
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoА вот тут тогда почему всё работает?

http://alenacpp.blogspot.ru/2008/01/const.html Потому что автор статьи видит звон, но не понимает где он.
const там совершенно не причем. А вот то что строка задана как "abc" это важно.
Задние констант в коде это совершенно отдельная тема. Задумайся, где эта строка "abc" хранится? В куче или на стеке?
Что происходит когда я пишу:
Код: plaintext
1.
2.
3.
void foo() {
   char *s = "abc";
}

?
Компилятор самопроизвольно добавит конструктор string? или strcpy? Где лежит "abc"? Может ли она быть затерта вызовом другой функции?
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017809
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так работает?Abstractionпропущено...
Нет. Если писать так:
Код: plaintext
1.
2.
3.
4.
5.
int& Add(int a, int b)
{
	int result = a+b;
	return result;
}

, то тоже получится фигня. Смотрите на то, что возвращает функция, а не на то, чему это возвращаемое значение присваивается.

А так работает?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int& Add(int a, int b)
{
	int result = a+b;
	return result;
}

int main() {
 int &res = Add(1, 2);
 std::cout << res;
}



Нет. Хотя если тестировать, то иногда может казаться, что оно работает.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017817
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvango
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
class Example
{
   int i;
   std::string s;
public:
   Example(int j) : i(j), s("abc"){};
};


const Example& f1(){ return Example(1); } // компилируется, не работает.
Example& f2(){ return Example(2); } // не компилируется, не работает.
const Example* f3(){ return new Example(3); } // компилируется, не работает. (нельзя будет удалить объект)
Example* f4(){ return new Example(4); } //  компилируется, работает.


int main(){
   const Example& e1 = f1();
   Example& e2 = f2();
   const Example* e3 = f3();
   Example* e4 = f4();

   delete e3;
   delete e4;
}





Вообще при таких проблемах часто нужно подумать о возврате объекта по значению.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017823
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvango
в VisualStudio всё копмилируется, только вот для f1() и f2() стоят предупреждения о возвращении ссылки на локальную переменную. Вопрос в том, будет ли это корректно работать?

Это не должно компилироваться по стандарту. Если студия это жрет, это проблемы частного компилятора.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017828
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Означает ли это, что при выходе из ф-и f1() и f2() соответственно соответствующие объекты уничтожаются несмотря на то, что на них указывает ссылка?


Да.



Почему ссылка не продлевает время жизни объекта?

Ссылка может продлить время жизни только локального временного объекта, а тут ты выходишь из функции вообще.
Верни объект по значению, он скопируется наружу, и все будет ок.

И почему для встроенных типов (int) случаи со ссылками работают?

Не работают и так, и так. Если ты гоняеш тесты какие то, то это тебе только кажется, что оно работает.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017875
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlayvangoА вот тут тогда почему всё работает?

http://alenacpp.blogspot.ru/2008/01/const.html Потому что автор статьи видит звон, но не понимает где он.
const там совершенно не причем. А вот то что строка задана как "abc" это важно.
Тут скорее вы не разобрались.

В примере по ссылке абсолютно не важно, как задана строка.

Там важно только то, что возвращается не ссылка или указатель, а значение.
В этом случае если на вызывающей стороне результат присвоить в ссылку, то возвращаемое значение сначала присваивается во временную переменную, время жизни которой продлевается до времени жизни ссылки, а ссылка ссылается на эту временную переменную, а не на значение созданное в функции (которое уничтожается сразу после присвоения во временную).

При этом компилятору позволяется для оптимизации опускать избыточные копирования временных объектов если время жизни у копии совпадает с исходным объектом. Но это отдельная тема.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017877
MasterZivА так работает?пропущено...


А так работает?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int& Add(int a, int b)
{
	int result = a+b;
	return result;
}

int main() {
 int &res = Add(1, 2);
 std::cout << res;
}



Нет. Хотя если тестировать, то иногда может казаться, что оно работает.
Не нет, а да.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38017891
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так работает?MasterZivпропущено...


Нет. Хотя если тестировать, то иногда может казаться, что оно работает.
Не нет, а да.
Не да, а нет :)
Все что я сказал не относится к случаю когда возвращается ссылка.
MasterZiv правильно сказал - работать будет некорректно, но вы об этом узнаете когда уже будет поздно.
При этом неважно во что присваивается результат.

Ссылку/указатель можно возвращать только на объекты с временем жизни больше чем вызванная функция.
Это:
1) глобальные и статические объекты
2) объекты созданные функцией в куче или другой глобальной памяти
3) объекты переданные в функцию извне (явно или неявно через состояние)
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38018039
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так работает?MasterZivпропущено...


Нет. Хотя если тестировать, то иногда может казаться, что оно работает.
Не нет, а да.

Это может только делать вид, что работает.
Ссылка возвращаемая ссылается на объект, время жизни которого истекло и он уничтожен.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38018040
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА так работает?пропущено...

Не нет, а да.
Не да, а нет :)
Все что я сказал не относится к случаю когда возвращается ссылка.
MasterZiv правильно сказал - работать будет некорректно, но вы об этом узнаете когда уже будет поздно.
При этом неважно во что присваивается результат.

Ссылку/указатель можно возвращать только на объекты с временем жизни больше чем вызванная функция.
Это:
1) глобальные и статические объекты
2) объекты созданные функцией в куче или другой глобальной памяти
3) объекты переданные в функцию извне (явно или неявно через состояние)

Не, на самом деле допустимо возвращать такие невалидные ссылки, но только при одном условии - что к этим объектам никогда не будет в программе обращения.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38018044
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про да и нет и эксперименты.
Тут как в анекдоте про Чапая, Петьку, таракана и научные изыскания — далеко не всякий эксперимент может являться подтверждением правильности какой-то теории.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38018886
Anatoly MoskovskyА так работает?пропущено...

Не нет, а да.
Не да, а нет :)
Все что я сказал не относится к случаю когда возвращается ссылка.
MasterZiv правильно сказал - работать будет некорректно, но вы об этом узнаете когда уже будет поздно.
При этом неважно во что присваивается результат.

Ссылку/указатель можно возвращать только на объекты с временем жизни больше чем вызванная функция.
Это:
1) глобальные и статические объекты
2) объекты созданные функцией в куче или другой глобальной памяти
3) объекты переданные в функцию извне (явно или неявно через состояние)
А если объект возвращается по значению, то есть ли вообще смысл его присваивать ссылке?
Можно просто его присвоить объекту и сработав RVO скомпилирует точно такой же код.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38019090
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так работает?А если объект возвращается по значению, то есть ли вообще смысл его присваивать ссылке?
Можно просто его присвоить объекту и сработав RVO скомпилирует точно такой же код.
Ну во-первых, не все компиляторы и не во всех случаях умеют RVO.
А во-вторых, не всегда при написании кода известно что функция вернет, ссылку или объект (например ожидается рефакторинг). В этом случае присваивать в ссылку оптимальнее, поскольку не требует копирования в случае если возвращается ссылка.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38019772
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем ответчикам спасибо за ответы, вдумчиво прочитал Ваши комметарии и почти во всём разобрался.

авторconst Example* f3(){ return new Example(3); } // компилируется, не работает. (нельзя будет удалить объект)
А как подробно это объяснить (константные объекты создаются в особой области памяти, но возвращаемый объект просто расположен в куче, а из-за того, что указатель показывает на константный объект, нельзя вызвать деструктор)? Кстати, VS2010 нормально вызывает деструктор.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38020063
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoпочти во всём разобрался.
Ага, щас :)
авторconst Example* f3(){ return new Example(3); } // компилируется, не работает. (нельзя будет удалить объект)
А как подробно это объяснить (константные объекты создаются в особой области памяти, но возвращаемый объект просто расположен в куче, а из-за того, что указатель показывает на константный объект, нельзя вызвать деструктор)? Кстати, VS2010 нормально вызывает деструктор.
Это абсолютно валидный код.
И никаких проблем с удалением объекта созданного в куче через указатель на константный объект нет, поскольку это атрибут указателя, а не объекта.

Другое дело стоит ли удалять объект если вам не разрешили его модифицировать. Возможно в будущем планируется как раз сделать его реально константным, или с многопоточным доступом. Но это уже ваше дело.

И называйте вещи своими именами - в C++ вам скорее всего никогда не придется вызвать деструктор явно: pointer->~Example().
А delete pointer - это не вызов деструктора, а удаление объекта (в т.ч. как всего лишь одна из частей этого процесса будет неявно вызван деструктор)
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38020141
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Про то, что не работает написал не я, я лишь пытаюсь во всём разобраться.

А что означает фраза "сслыка продлевает жизнь временного объекта? Верны ли комментарии к коду? И исчерпывается ли фраза про продление жизни этим и другими похожими случаями?

Example f(){ return Example(0); }

int main()
{
const Example& e1 = f(); // объект ВНУТРИ f() не удалился, пока на него указывает ссылка e1
Example e2 = f(); // объект ВНУТРИ f() удалился, а с помощью копирующего присваивания создался объект e2
Example e3(f()); // объект ВНУТРИ f() удалился, а помощью копирующего конструктора создался объект e3
return 0;
}
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38020349
ayvangoПро то, что не работает написал не я, я лишь пытаюсь во всём разобраться.

А что означает фраза "сслыка продлевает жизнь временного объекта? Верны ли комментарии к коду? И исчерпывается ли фраза про продление жизни этим и другими похожими случаями?

Example f(){ return Example(0); }

int main()
{
const Example& e1 = f(); // объект ВНУТРИ f() не удалился, пока на него указывает ссылка e1
Example e2 = f(); // объект ВНУТРИ f() удалился, а с помощью копирующего присваивания создался объект e2
Example e3(f()); // объект ВНУТРИ f() удалился, а помощью копирующего конструктора создался объект e3
return 0;
}
В выделенных может сработать RVO и конструкторы не вызовутся, а просто код соптимизируется до:
Example e2 = Example(0);
Example e3(Example(0));

Выделенные строчки одно и то же - конструктор копирования. Если хотите использовать оператор присваивания, то нужно так:
Example e3;
e3 = f();
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38020492
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoExample f(){ return Example(0); }
const Example& e1 = f(); // объект ВНУТРИ f() не удалился, пока на него указывает ссылка e1
нет, не так. при выходе из f() будет создан временный объект, куда скопируется возвращённый из функции результат. Если его не присваивать, то он сразу же разрушится, тоже автоматически. Но если его присвоить ссылке, то временный объект не будет разрушен до тех пор, пока существует эта ссылка на него.
объект ВНУТРИ f() будет разрушен в любом случае, есть там снаружи ссылка или нет.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38024028
Anatoly MoskovskyWhite Owlпропущено...
Потому что автор статьи видит звон, но не понимает где он.
const там совершенно не причем. А вот то что строка задана как "abc" это важно.
Тут скорее вы не разобрались.

В примере по ссылке абсолютно не важно, как задана строка.

Там важно только то, что возвращается не ссылка или указатель, а значение.
В этом случае если на вызывающей стороне результат присвоить в ссылку, то возвращаемое значение сначала присваивается во временную переменную, время жизни которой продлевается до времени жизни ссылки, а ссылка ссылается на эту временную переменную, а не на значение созданное в функции (которое уничтожается сразу после присвоения во временную).

При этом компилятору позволяется для оптимизации опускать избыточные копирования временных объектов если время жизни у копии совпадает с исходным объектом. Но это отдельная тема.
А если тип ссылки - это базовый класс, а присваивается ей объект наследованного класса возвращенный из функции по значению, то не будет утечек памяти?
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38024059
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
без утечек памяти?А если тип ссылки - это базовый класс, а присваивается ей объект наследованного класса возвращенный из функции по значению, то не будет утечек памяти?
Не будет утечек.
Т.к. временная переменная куда присваивается результат функции всегда имеет тип этого результата.
А ссылки на эту переменную на корректность ее уничтожения не влияют.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38024241
Anatoly Moskovskyбез утечек памяти?А если тип ссылки - это базовый класс, а присваивается ей объект наследованного класса возвращенный из функции по значению, то не будет утечек памяти?
Не будет утечек.
Т.к. временная переменная куда присваивается результат функции всегда имеет тип этого результата.
А ссылки на эту переменную на корректность ее уничтожения не влияют.
Ясно.

http://alenacpp.blogspot.ru/2008/01/const.html
Кстати, вот рассказывают что обязательно const нужен для ссылки на временный объект.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38024285
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ссылки на временный объект http://alenacpp.blogspot.ru/2008/01/const.html
Кстати, вот рассказывают что обязательно const нужен для ссылки на временный объект.
const нужен, потому что стандарт не разрешает приваивать временные значения в неконстантные ссылки, а не из-за технических каких-то причин.
А компиляторы которые попускают такое просто не придерживаются стандарта. Например VS6 много чего не по стандарту делал, да и следующие версии тоже, хоть и постепенно фиксят это.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38112648
Такой вариант понятен:
Код: plaintext
1.
2.
3.
4.
5.
string f() { 
 return string("abc"); // это временный объект
}

string const& a = f();



Код: plaintext
1.
2.
3.
string f() { return "abc"; } // аналогично

string const& a = f();



А в данном случае возвращаемый объект является временным и продлевается ли его жизнь?:
Код: plaintext
1.
2.
3.
4.
5.
6.
string f() { 
string s = "abc"; // уже не временный объект
s += "def";
return s; }

string const& a = f();
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38112871
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в данном случае,

Неважно что там внутри функции.
Речь про другие временные объекты - те, куда присаиваются результаты вызова функции перед инициализацией ими ссылки.
...
Рейтинг: 0 / 0
Объясните раз и навсегда про возвращение из функции указателя и ссылки
    #38113699
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в данном случае
А в данном случае возвращаемый объект является временным и продлевается ли его жизнь?:

Код: plaintext
1.
2.
3.
4.
5.
6.
string f() { 
string s = "abc"; // уже не временный объект
s += "def";
return s; }

string const& a = f();




В данном случае из функии также возвращается временный объект.
При выходе из функции переменная s копируется в новый временный объект и возвращается.

Снаружи функции тут также происходит продление времени жизни временного объекта, возвращённого из функции.

Всегда, когда функция возвращает что-то по значению, возвращается временный объект (также в широком смысле слова, включая встроенные типы типа int, double и т.д.).
Также всегда, когда из функции возвращается временный объект и им инициализируется ссылка (она обязана быть константной), продлевается время жизни этого временного объекта до выхода из области дейсвия ссылки.
...
Рейтинг: 0 / 0
45 сообщений из 45, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Объясните раз и навсегда про возвращение из функции указателя и ссылки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]