Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
Fangod
8 / 8 / 0
Регистрация: 07.10.2011
Сообщений: 164
#1

Очистка памяти при завершении работы функции, как правильно возвращать значения?

05.06.2016, 16:53. Просмотров 811. Ответов 9
Метки нет (Все метки)

Я вывел для себя 2 способа возвращать значения работы функции

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
string Add(string a1, string a2) {
    string returnStr;
    returnStr += a1 + "\n";
    returnStr += a2 + "\n";
    return returnStr;
}
 
 
void Add2(string a1, string a2, string& returnStr) {
    returnStr += a1 + "\n";
    returnStr += a2 + "\n";
}
 
 
int main() {
    setlocale(LC_ALL, "Rus");
 
 
    cerr << Add("Чык", "Чырык");
 
    cerr << "-----------------\n";
 
    string testStr;
    Add2("Чык", "Чырык", testStr);
    cerr << testStr;
 
 
    system("pause");
    return 0;
}
Почему-то все предпочитают второй, хотя первый гораздо понятней, в книгах говорилась о том, что значение возвращаемое функцией из первого способа может быть уже "мертво"

Как тогда правильно возвращать значения? Разве результат функции передает ссылку на переменную? А не сразу значение? Зачем тогда вообще в языке есть возможность возвращать значение через функцию, если в любой момент все может рухнуть?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.06.2016, 16:53
Ответы с готовыми решениями:

Как правильно возвращать указатели из функции
Как правильно возвращать указатели? int* retPointer() { int* k; int j = 5; k =...

Как правильно возвращать строковый литерал из функции
Строковый литерал по сути представляет собой указатель на данные. Но что если...

Правильно возвращать значение из функции
Есть недопонимание в этом вопросе. Понимаю, что локальные переменные вернуть...

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

Ошибка при завершении работы программы
Написал программу, но при завершении выдает ошибку. Помогите понять с чем это...

9
Stitch Igorek
47 / 47 / 31
Регистрация: 02.04.2016
Сообщений: 308
Завершенные тесты: 1
05.06.2016, 17:07 #2
Лучший ответ Сообщение было отмечено Fangod как решение

Решение

2й способ работает побыстрее просто, за счет того, что функция сразу пишет результат в переменную returnStr, ссылку на которую передали ей при вызове, а первый способ считает, сохраняет в локальную переменную и копирует свои расчеты в переменную для которой считала.

Добавлено через 5 минут
к тому же функция в результате своей работы может посчитать 2 и более переменных, например
C++
1
2
3
4
5
6
void A(int &a; int &b; int c&)
{
     a += b;
     b = b * c;
     c = (a + b) * 2;
}
не получиться посчитать способом номер 1.
2
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
05.06.2016, 17:42 #3
Передаваемые string a1, string a2 тоже копируются.
Fangod, так ещё можно:
C++
1
2
3
void Add2(const string &a1, const string &a2, string& returnStr) {
    returnStr = a1 + a2;
}
1
Stitch Igorek
47 / 47 / 31
Регистрация: 02.04.2016
Сообщений: 308
Завершенные тесты: 1
05.06.2016, 18:01 #4
а можно так =)
C++
1
2
3
4
inline string Add(string a1, string a2)
{
    return (a1 + a2);
}
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
05.06.2016, 18:03 #5
Компилятор будет иметь ввиду.
0
warhast
19 / 19 / 4
Регистрация: 02.02.2014
Сообщений: 74
05.06.2016, 18:07 #6
Add и Add2 в итоге станут одним и тем же кодом - см. (N)RVO, там что можно писать как удобнее - скорость уж точно не изменится.
0
Stitch Igorek
47 / 47 / 31
Регистрация: 02.04.2016
Сообщений: 308
Завершенные тесты: 1
05.06.2016, 20:25 #7
Цитата Сообщение от warhast Посмотреть сообщение
Add и Add2 в итоге станут одним и тем же кодом - см. (N)RVO, там что можно писать как удобнее - скорость уж точно не изменится.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <string>
#include <time.h>
 
std::string Sum1(std::string a, std::string b)
{
    std::string result = a + b;
    return result;
}
 
void Sum2(std::string a, std::string b, std::string &result)
{
    result = a + b;
}
 
int main()
{
    std::string a("Odnazhdy v studenuju zimnjuju poru "), b("Ja iz lesu vyshel i snova zashel");
    const int N = 100000;
    std::string result;
 
    clock_t start = clock();
    
    for (int i(0); i < N; i++)
    {
        result = Sum1(a, b);
    }
 
    clock_t end = clock();
 
    std::cout << double(end - start) / CLOCKS_PER_SEC << std::endl;
 
    start = clock();
 
    for (int i(0); i < N; i++)
    {
        Sum2(a, b, result);
    }
 
    end = clock();
 
    std::cout << double(end - start) / CLOCKS_PER_SEC << std::endl;
 
    system("pause");
}

Мой компилятор с твоими суждениями не согласен.
0
warhast
19 / 19 / 4
Регистрация: 02.02.2014
Сообщений: 74
05.06.2016, 20:59 #8
Компилятор не может "соглашаться" или "не соглашаться", у него обычно есть название, версия, опции, какие-то из которых используют для компиляции своих поделий даже те, кто ни о чем таком и не подозревают. А вообще см. стандарт п. 6.6.3 - "A copy or move operation associated with a return statement may be elided ...".
0
Mr.X
Эксперт С++
3178 / 1705 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
06.06.2016, 11:22 #9
Цитата Сообщение от Stitch Igorek Посмотреть сообщение
Мой компилятор с твоими суждениями не согласен
А вы сколько раз запускали? Я запустил по нескольку раз на разных онлайн-компиляторах, результаты абсолютно случайные, иногда значения равны, иногда какое-то больше. Закономерности никакой нет.
0
warhast
19 / 19 / 4
Регистрация: 02.02.2014
Сообщений: 74
06.06.2016, 15:02 #10
Вообще говоря, однократный проход по таким замерам не имеет смысла - достаточно системе лишний раз переключить потоки и результаты можно отравлять на помойку.
0
06.06.2016, 15:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.06.2016, 15:02

Закрытие именованного канала при завершении работы программы
Добрый день. Пример: int main() { CreateNamedPipe(...); return 0;...

Прерывание работы функции, если при введенных значения вычисление невозможно
Есть функция типа double, которая возвращает значение выражения. Нужно сделать...

Как правильно записать в виде функции выделение памяти для двумерного массива и ее освобождение
Здравствуйте! Подскажите, как правильно записать в виде функции выделение...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru