Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
184 / 24 / 4
Регистрация: 18.01.2011
Сообщений: 359
1

Касательно указателей и ссылок.

30.01.2012, 12:12. Показов 1437. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Цитирую фразу из популярной ныне книги Айвора Хортона.
"Никогда не возвращайте из функции ссылку на локальную переменную"
Так вот. Не понятно почему так категорично все. По моему даже оч. удобно создать лок. переменную, присвоить ей ссылку на объект. поработать с ним. переменную удалить. Я вот подобным образом свою программу делаю. Озадачила меня эта вот фраза. Прошу помощи в разъяснении данного вопроса.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.01.2012, 12:12
Ответы с готовыми решениями:

Касательно указателей и функций
Уважаемые, назрел вот какой вопрос. Делаю вот так: TVozmGrup MassVG; GetVGArroundVG(MassVG); ...

Сравнение указателей и ссылок.
Не совсем так для них компилятор вырабатывает разный ассемблерный код int main() { //mov...

Использование ссылок и указателей
Добрый вечер Помогите разобраться и понять «Использование ссылок и указателей» Прочел много...

Ступор в возврате указателей и ссылок
Изучаю С++ базовый курс от Шилтда, все проходил на твердую четверку, и на предпоследней теме про...

16
Полярный
476 / 448 / 158
Регистрация: 11.09.2011
Сообщений: 1,156
30.01.2012, 12:13 2
Ну все путем практики осваивается
Локальный объект - он на то и локальный - что бы потом и "самоликвидироваться" после выхода за область действия. А вы, понимаете, того, использовать его намереваетес.
Если прям надо, просто верните обеъкт, не указатель\ссылку.
1
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
30.01.2012, 12:18 3
Цитата Сообщение от Андрей2011 Посмотреть сообщение
"Никогда не возвращайте из функции ссылку на локальную переменную"
Цитата Сообщение от Андрей2011 Посмотреть сообщение
создать лок. переменную, присвоить ей ссылку на объект. поработать с ним. переменную удалить.
Это два разных высказывания. Вы уж определитесь.
0
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
30.01.2012, 12:42 4
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
#include <iostream>
 
class Foo
{
public:
    Foo(int foo):
    m_foo(new int(foo))
    {
    }
 
    Foo(const Foo& source):
    m_foo(new int(source.foo()))
    {
    }
 
    ~Foo()
    {
        delete m_foo;
    }
 
    int foo() const
    {
        return *m_foo;
    }
 
private:
    int *m_foo;
};
 
Foo& bar()
{
    Foo res(10);
 
    return res;
}
 
int main()
{
    std::cout << bar().foo() << std::endl; // Ooops!
 
    return 0;
}
Добавлено через 8 минут
Вот так понагляднее будет:
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
46
47
48
49
50
51
52
53
54
#include <iostream>
 
class Foo
{
public:
    Foo(int foo):
    m_foo(new int(foo))
    {
        std::cout << "Foo::Foo(int) : " << m_foo << std::endl;
    }
 
    Foo(const Foo& source):
    m_foo(new int(source.foo()))
    {
        std::cout << "Foo::Foo(const Foo&) : " << m_foo << std::endl;
    }
 
    ~Foo()
    {
        std::cout << "Foo::~Foo() : " << m_foo << std::endl;
        
        delete m_foo;
    }
 
    int foo() const
    {
        return *m_foo;
    }
 
private:
    int *m_foo;
};
 
Foo& bar()
{
    std::cout << "Foo& bar() : before Foo res(10);" << std::endl;
    Foo res(10);
    std::cout << "Foo& bar() : after Foo res(10);" << std::endl;
    
    std::cout << "Foo& bar() : res.foo() : " << res.foo() << std::endl;
    
    return res;
}
 
int main()
{
    std::cout << "int main() : before Foo goo = bar();" << std::endl;
    Foo goo = bar();
    std::cout << "int main() : after Foo goo = bar();" << std::endl;
    
    std::cout << "int main() : goo.foo() : " << goo.foo() << std::endl; // Ooops!
 
    return 0;
}
Вывод:
Код
int main() : before Foo goo = bar();
Foo& bar() : before Foo res(10);
Foo::Foo(int) : 0x5c0e78
Foo& bar() : after Foo res(10);
Foo& bar() : res.foo() : 10
Foo::~Foo() : 0x5c0e78
Foo::Foo(const Foo&) : 0x5c0e78
int main() : after Foo goo = bar();
int main() : goo.foo() : 6041520
Foo::~Foo() : 0x5c0e78
Обратить внимание на строку 7. Деструктор вызывается до копирования объекта. Беда!
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
30.01.2012, 12:46 5
Айвор Хортон неточен
Вот такой код вполне допустим (проверено)
C
1
2
3
4
5
char *foo(int n)
{ static char s[10];
    itoa(n, s, 10);
    return &s[0];
}
Вот если бы s была без слова static, тогда Ой.
2
184 / 24 / 4
Регистрация: 18.01.2011
Сообщений: 359
30.01.2012, 14:14  [ТС] 6
Цитата Сообщение от dimcoder Посмотреть сообщение
Если прям надо, просто верните обеъкт, не указатель\ссылку.
Ну он же копируется тогда? Блин.(((
Вот мой код:
C++
1
2
3
4
5
6
7
8
9
10
    
//сначала я создаю массив объектов TTo4ka;
//ф-я GetPoint - ищет нужный объект.
.
.
.
//тут вот, отдельная ф-я. я создаю локальный объект типа TTo4ka
//дабы присвоить ей, нейденый с помощью ф-и GetPoint объект.
TTo4ka To4ka;
    To4ka =  GetPoint(X,Y);
//тут есть еще вот какие моменты:
//1.ф-я GetPoint -возвращает ссылку на объект TTo4ka
//ибо чтоб не копировалась не создавалась.
//2.если буду возвращать не ссылку а объект то будет тогда копироваться!!
//3.если принимает ссылку не созданный локальный объект то программа ругается.
//4. TTo4ka To4ka; - это тоже плохо. т.к. у меня создаются новые объекты типа TTo4ka в //локальной ф-и. Или не плохо это?
0
Полярный
476 / 448 / 158
Регистрация: 11.09.2011
Сообщений: 1,156
30.01.2012, 14:23 7
Цитата Сообщение от Андрей2011 Посмотреть сообщение
4. TTo4ka To4ka; - это тоже плохо. т.к. у меня создаются новые объекты типа TTo4ka в //локальной ф-и. Или не плохо это?
Кто вам такое сказал? Ну что ж теперь вообще не создавать ничего в функциях?

Не по теме:

А то оперативка расплавиться :D



Короче вот пример:
C++
1
2
3
4
5
int& func()         //Оч плохо
{
   int x = 19;
   return *x;
}
Это то что вы хотите сказать/сделать?
Или так:
C++
1
2
3
4
5
int& func(int *x)   //Хорошо
{
   *x = 19;
   return x;
}
0
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
30.01.2012, 14:27 8
Цитата Сообщение от Андрей2011 Посмотреть сообщение
//1.ф-я GetPoint -возвращает ссылку на объект TTo4ka
Насколько я помню по предыдущей теме, проблем быть не должно, поскольку GetPoint ищет точку не в локальном массиве, следовательно, и ссылку она возвращает на не локальный (по отношению к ней) объект.
Цитата Сообщение от Андрей2011 Посмотреть сообщение
//2.если буду возвращать не ссылку а объект то будет тогда копироваться!!
Если это вопрос, то да. Если констатация факта... не знаю, что сказать
Цитата Сообщение от Андрей2011 Посмотреть сообщение
//3.если принимает ссылку не созданный локальный объект то программа ругается.
Нифига не понял
Цитата Сообщение от Андрей2011 Посмотреть сообщение
//4. TTo4ka To4ka; - это тоже плохо. т.к. у меня создаются новые объекты типа TTo4ka в //локальной ф-и. Или не плохо это?
Всё относительно. Плохо-не плохо... Сразу не сказать. Если функция выглядит так:
C++
1
2
3
4
5
6
void func()
{
    TTo4ka a;
    TTo4ka b;
    TTo4ka c;
}
тогда конечно плохо, ибо создаются три объекта, которые потом никак не используются. А если так:
C++
1
2
3
4
5
6
void func()
{
    TTo4ka a;
    
    // Что-то делаем с объектом a для того, чтобы получить какие-то реальные результаты
}
то ничего плохого в локальном объекте нет.
0
184 / 24 / 4
Регистрация: 18.01.2011
Сообщений: 359
30.01.2012, 14:30  [ТС] 9
не совсем. вернее совсем нет. )) Ф-я выглядит так:
C++
1
2
3
4
5
6
7
 TTo4ka &GetPoint(const short &X,const short &Y)
{
 short Nom = p_MassivTo4ek[X][Y]; //просто указатель на массив хранящий номер 
                                                //объекта по точкам Х и Y
 return p_To4ka[Nom-1];  //указатель на массив объектов. Можно их считать глобальными
                                   //т.к. под них выделена память динамическая.
}
Суть вопроса заключается в том что хочу, после нахождения нужного объекта в ф-и, вернуть его,
или его ссылку, или указатель на объект, дабы в другой ф-и можно было с ним работать. изменять
и т.п. Но! Но хотелось бы все это действо провернуть ПРАВИЛЬНО не тратя лишней памяти и т.п.
0
Полярный
476 / 448 / 158
Регистрация: 11.09.2011
Сообщений: 1,156
30.01.2012, 14:33 10
Цитата Сообщение от Андрей2011 Посмотреть сообщение
return p_To4ka[Nom-1]; *//указатель на массив объектов. Можно их считать глобальными
* * * * * * * * * * * * * * * * * *//т.к. под них выделена память динамическая.
Это вы называете "возвратить локальную переменную"!?!?

И почему если под переменную выделена память динамически, она вдруг становиться глобальной?!?

Цитата Сообщение от Андрей2011 Посмотреть сообщение
short Nom = p_MassivTo4ek[X][Y]; //просто указатель на массив хранящий номер
nom - не указатель
0
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
30.01.2012, 14:34 11
Андрей2011, не всегда не тратя памяти значит правильно. Например,если в классе хранится строка, я предпочту в геттере вернуть её копию, а не константную ссылку на неё. Потому что константность легко можно отменить и прострелить себе ногу. Хотя всё, конечно, зависит от задачи (точнее даже, от требований).
0
184 / 24 / 4
Регистрация: 18.01.2011
Сообщений: 359
30.01.2012, 14:43  [ТС] 12
Вот. Увжаемый, silent_1991, меня понял. Пусть и отчасти))
Просто получается вот какая штука. Объект TTo4ka содержит в себе штук 10 переменных и еще 2 массива по 4 элемента в каждом.
А теперь представьте.
Человек ставит "точку" (ход делает) и запусается эта ф-я. локальная. которая локально создает 4 такие вот точки потом их удаляет естественно. Т.е. ... память выделилась и она же вернулась. Но правильно ли это? все же на создание одного объекта уходит много байт.
и я в книге Айрона Хортона сегодня прочитал что он в примере в своем делает такую штуку:
Он, из ф-и возвращает ссылку на объект а принимает её, ссылку, указатель!
т.е. как-то так:
C++
1
2
    TTo4ka *To4ka;
    *To4ka =  GetPoint(X,Y);
- и тогда, предполагаю, лишние объекты не создаются. А указатель потом можно и обнулить.

Добавлено через 5 минут
Цитата Сообщение от dimcoder Посмотреть сообщение
Это вы называете "возвратить локальную переменную"
- это я называю возвратом ссылки на объект.

Цитата Сообщение от dimcoder Посмотреть сообщение
nom - не указатель
- имелось ввиду что p_MassivTo4ek - указатель на массив.
0
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
30.01.2012, 14:45 13
Андрей2011, я не совсем понял, о чём вы (как указатель может "принять" ссылку), но суть приёма снова не понимаю. Факт в том, что функции предназначены для выполнения некоторых локальных действий либо для преобразования информации. И возвращать из функции новый объект зачастую единственно правильное решение.
0
184 / 24 / 4
Регистрация: 18.01.2011
Сообщений: 359
30.01.2012, 14:48  [ТС] 14
вот:
C++
1
2
    TTo4ka *To4ka;
    To4ka =  &GetPoint(X,Y);
не совсем понял что написал...но по крайней мере програма работает (не проверял на сколько правильно) и не создает новых объектов!
0
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
30.01.2012, 14:49 15
Андрей2011, а какая здесь разница между ссылкой и указателем (кроме отбрасывания синтаксических прелестей ссылок и вновь появившейся возможностью выстрелить себе в ногу)?
1
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
30.01.2012, 15:06 16
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
struct Unit
{
    int a;
 
    Unit(int v):a(v){};
    Unit():a(0){};
    ~Unit(){};
 
    Unit& operator +=(Unit& u)
    {
        a+=u.a;
        return *this;
    }
    Unit& operator = (Unit& u)
    {
        a= u.a;
        return *this;
    }
 
};
 
Unit&& test (Unit&& a)
{
    Unit a2;
    a2+=a;
    return std::forward<Unit> (a2);//возвращается reference только rvalue
};
 
 
int main()
{
    Unit u = test(Unit(10));
    return 0;
}
давайте обсудим. может и не совсем в тему. но все про возврат ссылок на локальные или временные объекты из тела функции. что думаете по этим нововведениям? плюсы очевидны, дополнительных объектов создано не будет. Но все таки что насчет этой темы - возврат ссылок. Разве с новым стандартом не стоит уточнить, что нельзя возвращать lvalu reference на временный объект. Я прав?
0
184 / 24 / 4
Регистрация: 18.01.2011
Сообщений: 359
30.01.2012, 15:10  [ТС] 17
о как замутил. О_о
0
30.01.2012, 15:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.01.2012, 15:10
Помогаю со студенческими работами здесь

Совместное использование указателей и ссылок
int *ptr; int &amp;ref = *ptr; ref = 1; Вот и весь вопрос. Ничего плохого в этом нет?

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

Объясните суть ссылок и указателей в коде
Всем добрый день! В общем, есть код (не судите, что примера попроще я не подобрал, просто подумал,...

Операции присвоения с использованием указателей и ссылок
с помощью указателя pOcenka присвойте соответствующей переменной (o_inf или o_math) значение равное...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru