Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
Ivan_32
28 / 24 / 0
Регистрация: 03.02.2010
Сообщений: 66
1

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

11.09.2010, 09:49. Просмотров 2051. Ответов 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: Меня так же посещала мысль сделать из этого класса функтор, это конечно решит проблему но выглядит как то уж криво слишком, с таким же успехом можно будет и обычную функцию использовать. Хочется настоящей неподдельной инкапсуляции, так что б тип данным выглядел взаправдашним
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.09.2010, 09:49
Ответы с готовыми решениями:

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

арифметика указателей
Здравствуйте. Объясните, пожалуйста, код из инета: 1. &quot;переменная A типа...

Арифметика указателей
есть size_t * pointer_1; logfile_f(&quot;\npointer_1 is 0x%X&quot;, pointer_1); есть...

Арифметика указателей
Эквивалентны ли эти две записи? int *p1=new int; int *p2=p1; или ...

Арифметика указателей (указатель на void*)
У меня есть указатель на void*, который я получил с помощью void *beginPointer...

13
ForEveR
В астрале
Эксперт С++
7996 / 4755 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
11.09.2010, 10:47 2
Ivan_32, List* a=new List(0); живет пока не будет очищена память оператором delete.
List b(0); до конца области видимости.
1
Nick Alte
Эксперт С++
1647 / 1019 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 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, остался в памяти мёртвым грузом
1
Ivan_32
28 / 24 / 0
Регистрация: 03.02.2010
Сообщений: 66
11.09.2010, 11:07  [ТС] 4
В который раз убеждаюсь что на самые простые вопросы отвечают наиболее развернуто
Тем не менее, оставалась проблема с этой конструкцией:
(*a)[0];
Решил в меру уродливым способом:
List& a= * new List(0);
0
ForEveR
В астрале
Эксперт С++
7996 / 4755 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
11.09.2010, 11:12 5
Ivan_32, А для чего именно такое объявление?

List& t=(*a);

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

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

Не по теме:

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

0
Andrew_Lvov
Эксперт С++
260 / 190 / 10
Регистрация: 19.08.2010
Сообщений: 760
Записей в блоге: 1
14.09.2010, 00:20 13
Цитата Сообщение от fasked Посмотреть сообщение
Но при этом можно создать смарт-пойнтер с перегруженными операторами "*" и "[]".
Только правильно ли ?
0
fasked
Эксперт С++
4982 / 2561 / 241
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
14.09.2010, 00:26 14
Цитата Сообщение от Andrew_Lvov Посмотреть сообщение
Только правильно ли ?
В самом первом сообщении используется динамическое выделение памяти, так что смайрт-пойнтер тут возможно и был бы в тему.
По поводу operator[] для списка - конечно бред.
Хотя указатель может указывать например на массив списков.
0
14.09.2010, 00:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.09.2010, 00:26

Индексация массивов, арифметика указателей
инициализирую одномерный массив и делаю на него указатель const int...

Как работает арифметика указателей, память массивов
В книге : х Это тоже самое что *(х+3)=120 Птм он грит : значение х в данном...

Замена максимального элемента массива на среднее арифметическое (арифметика указателей)
Написать программу, которая заменяет значение максимального элемента массива на...


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

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

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