Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.71
Ivan_32
28 / 24 / 4
Регистрация: 03.02.2010
Сообщений: 66
#1

Способы создания объектов и арифметика указателей - C++

11.09.2010, 09:49. Просмотров 1772. Ответов 13
Метки нет (Все метки)

Вот сам код:
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
class ListNode
{
public:
    ListNode(int val)
    {
        next=NULL;
        i=val;
    }
    ListNode* next;
    ListNode* prev;
    int i;
};
 
class List
{
public:
    ListNode* first;
    List(int i)
    {
        first=new ListNode(i);
    };
    void Add(int i)
    {
        ListNode* last=this->first;
        while(last->next)
        {
            last=last->next;
        }
        last->next=new ListNode(i);
    };
    int& operator[](int index)
    {
        ListNode* temp=this->first;
        for(int i=0;i<index;i++)
        {
            temp=temp->next;
        }
        return temp->i;
    };
};
int main()
{
    List* a=new List(1);
    List& t=(*a);
    a->Add(99);
    a->Add(88);
    printf("%i",t[2] /*(*a)[2]*/ );
    getch();
    return 0;
}
Проблема следующая:
Я страх как не хочу видеть в коде ссылочные типы на объект и уж тем более очень не хочется видеть выражения вида (*a)[0]. Опять же не очень хочется делать некий абстрактный класс для сокрытия арифметики указателей( да и можно ли такое сделать в данном случае? ), да и не знаю как.
Как можно данную проблему решить и что не так у меня в классах, может быть я где то допустил ошибку?

Так же интересует чем различаются данные способы создания объектов:
List* a=new List(0);
List b(0);
Я так понимаю первый живет ровно до тех пор пока на него ссылается хотя бы один указатель, а вот второй это просто напросто ссылка на объект? Первый не умрет если на него будет что либо ссылается, а вот второй умрет сразу после выхода из области видимости?

PS: Меня так же посещала мысль сделать из этого класса функтор, это конечно решит проблему но выглядит как то уж криво слишком, с таким же успехом можно будет и обычную функцию использовать. Хочется настоящей неподдельной инкапсуляции, так что б тип данным выглядел взаправдашним
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
11.09.2010, 10:47     Способы создания объектов и арифметика указателей #2
Ivan_32, List* a=new List(0); живет пока не будет очищена память оператором delete.
List b(0); до конца области видимости.
Nick Alte
Эксперт С++
1605 / 997 / 118
Регистрация: 27.09.2009
Сообщений: 1,923
Завершенные тесты: 1
11.09.2010, 10:58     Способы создания объектов и арифметика указателей #3
Неправильные у вас тут мысли. Первый живёт ровно до тех пор, пока его не удалят. Если его адрес потеряется, удалить его будет невозможно и он так и будет висеть в памяти мёртвым грузом, это называется утечкой памяти. Если его удалить, но сохранить адрес и потом им воспользоваться, это тоже очень неприятная ошибка.
Второй будет существовать в пределах области, в которой определён:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int* foo()
{
    int *a = new int(7);
    int b = 8;
    for(int c=0; c<9; ++c){
        int *d = new int(10);   // Этот указатель создаётся в начале каждого шага цикла
        std::cout << c;
        // В конце цикла указатель d уничтожается, замусорив память "осиротевшим" блоком, выделенным под объект int
    }   // После этой скобки пропадает переменная c, как и не было её
    return a;
}   // После этой скобки пропадает начисто b и указатель a, но его значение возвращается из функции
 
void bar()
{
    int *aa = foo();  // Адрес объекта, созданного в foo и хранящегося там в a, попадает в aa
    *aa = 5;           // Правильно
    delete aa;         // Уничтожаем созданный объект, освобождаем занятую память, при этом для объектов вызывается деструктор
    int *bb = foo(); // Создаётся ещё один объект
    *aa = *bb;       // aa уже удалён, это недопустимая смысловая ошибка, но компилятор её пропустит. Может вызывать сбой программы или порчу данных в произвольном месте.
}   // Указатели aa и bb уничтожены, но объект, на который указывал bb, остался в памяти мёртвым грузом
Ivan_32
28 / 24 / 4
Регистрация: 03.02.2010
Сообщений: 66
11.09.2010, 11:07  [ТС]     Способы создания объектов и арифметика указателей #4
В который раз убеждаюсь что на самые простые вопросы отвечают наиболее развернуто
Тем не менее, оставалась проблема с этой конструкцией:
(*a)[0];
Решил в меру уродливым способом:
List& a= * new List(0);
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
11.09.2010, 11:12     Способы создания объектов и арифметика указателей #5
Ivan_32, А для чего именно такое объявление?

List& t=(*a);

Зачем ссылка на число которое хранится по адресу a?
Ivan_32
28 / 24 / 4
Регистрация: 03.02.2010
Сообщений: 66
11.09.2010, 11:17  [ТС]     Способы создания объектов и арифметика указателей #6
Это что бы не писать (*a)[0], а писать t[0]. Тут смысл в том что без обращения по значению [] воспринимается как тот же *, то есть косвенное обращение, ну и естественно ни о каком операторе речи и не идет. С этим и воюю. Жаль нельзя сделать перегрузку [] именно для List*. Хотя наверно если подумать можно сделать класс указателя на класс List и в нем уже что то шаманить.
Andrew_Lvov
Эксперт С++
259 / 189 / 5
Регистрация: 19.08.2010
Сообщений: 758
Записей в блоге: 1
12.09.2010, 00:41     Способы создания объектов и арифметика указателей #7
Ivan_32,
C++
1
List a = List(1);
Добавлено через 1 минуту
И ещё:
вы ведь знаете, почему в std::list нет оператора [] ?

Добавлено через 3 минуты
А ещё
Цитата Сообщение от Ivan_32 Посмотреть сообщение
ListNode* first;
Нужно бы обьявить как private.
Ivan_32
28 / 24 / 4
Регистрация: 03.02.2010
Сообщений: 66
14.09.2010, 00:05  [ТС]     Способы создания объектов и арифметика указателей #8
Вот теперь это становится понятным. Значит это просто технически невозможно, раз даже в STL-контейнере такой фичи нет. Спасибо всем.
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
14.09.2010, 00:09     Способы создания объектов и арифметика указателей #9
Цитата Сообщение от Ivan_32 Посмотреть сообщение
Значит это просто технически невозможно
Технически то это возможно, но тогда это уже и не список получится, а черти знает что.
Хохол
Эксперт C++
475 / 443 / 13
Регистрация: 20.11.2009
Сообщений: 1,292
14.09.2010, 00:10     Способы создания объектов и арифметика указателей #10
Что значит технически невозможно? Скорее синтаксически невозможно... Пользуйтесь своим вариантом с лишней ссылкой, ничего плохого в нем вроде нет.
А оператора [] в STL'ском list'е нет видимо потому что список не поддерживает произвольного доступа, только последовательный, поэтому не стали включать в интерфейс внешне простую операцию, работающую на самом деле медленно.
Andrew_Lvov
Эксперт С++
259 / 189 / 5
Регистрация: 19.08.2010
Сообщений: 758
Записей в блоге: 1
14.09.2010, 00:13     Способы создания объектов и арифметика указателей #11
Ребята, уточняйте вопрос, по к-рому идёт дисскусия.
Переопределить operator[] для типа Object* (т.е. для указателя на объект класса) действительно нельзя.
fasked
14.09.2010, 00:18
  #12

Не по теме:

Цитата Сообщение от Andrew_Lvov Посмотреть сообщение
Переопределить operator[] для типа Object* (т.е. для указателя на объект класса) действительно нельзя.
Но при этом можно создать смарт-пойнтер с перегруженными операторами "*" и "[]".

Andrew_Lvov
Эксперт С++
259 / 189 / 5
Регистрация: 19.08.2010
Сообщений: 758
Записей в блоге: 1
14.09.2010, 00:20     Способы создания объектов и арифметика указателей #13
Цитата Сообщение от fasked Посмотреть сообщение
Но при этом можно создать смарт-пойнтер с перегруженными операторами "*" и "[]".
Только правильно ли ?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.09.2010, 00:26     Способы создания объектов и арифметика указателей
Еще ссылки по теме:

Арифметика указателей (указатель на void*) C++
C++ Какие способы создания приложения на этом языке Вы знаете?
Объяснить от чего зависит размер указателя и что такое арифметика указателей C++
C++ Замена максимального элемента массива на среднее арифметическое (арифметика указателей)
C++ Способы создания динамической квадратичной матрицы вида matrix[N][N]

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

Или воспользуйтесь поиском по форуму:
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
14.09.2010, 00:26     Способы создания объектов и арифметика указателей #14
Цитата Сообщение от Andrew_Lvov Посмотреть сообщение
Только правильно ли ?
В самом первом сообщении используется динамическое выделение памяти, так что смайрт-пойнтер тут возможно и был бы в тему.
По поводу operator[] для списка - конечно бред.
Хотя указатель может указывать например на массив списков.
Yandex
Объявления
14.09.2010, 00:26     Способы создания объектов и арифметика указателей
Ответ Создать тему
Опции темы

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