С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
28 / 24 / 0
Регистрация: 03.02.2010
Сообщений: 66

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

11.09.2010, 09:49. Показов 3902. Ответов 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
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.09.2010, 09:49
Ответы с готовыми решениями:

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

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

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

13
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
11.09.2010, 10:47
Ivan_32, List* a=new List(0); живет пока не будет очищена память оператором delete.
List b(0); до конца области видимости.
1
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
11.09.2010, 10:58
Неправильные у вас тут мысли. Первый живёт ровно до тех пор, пока его не удалят. Если его адрес потеряется, удалить его будет невозможно и он так и будет висеть в памяти мёртвым грузом, это называется утечкой памяти. Если его удалить, но сохранить адрес и потом им воспользоваться, это тоже очень неприятная ошибка.
Второй будет существовать в пределах области, в которой определён:
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
28 / 24 / 0
Регистрация: 03.02.2010
Сообщений: 66
11.09.2010, 11:07  [ТС]
В который раз убеждаюсь что на самые простые вопросы отвечают наиболее развернуто
Тем не менее, оставалась проблема с этой конструкцией:
(*a)[0];
Решил в меру уродливым способом:
List& a= * new List(0);
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
11.09.2010, 11:12
Ivan_32, А для чего именно такое объявление?

List& t=(*a);

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

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

Не по теме:

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

0
Эксперт С++
 Аватар для Andrew_Lvov
261 / 191 / 10
Регистрация: 19.08.2010
Сообщений: 760
Записей в блоге: 1
14.09.2010, 00:20
Цитата Сообщение от fasked Посмотреть сообщение
Но при этом можно создать смарт-пойнтер с перегруженными операторами "*" и "[]".
Только правильно ли ?
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
14.09.2010, 00:26
Цитата Сообщение от Andrew_Lvov Посмотреть сообщение
Только правильно ли ?
В самом первом сообщении используется динамическое выделение памяти, так что смайрт-пойнтер тут возможно и был бы в тему.
По поводу operator[] для списка - конечно бред.
Хотя указатель может указывать например на массив списков.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.09.2010, 00:26
Помогаю со студенческими работами здесь

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

Индексация массивов, арифметика указателей
инициализирую одномерный массив и делаю на него указатель const int N = 6; int X = {9,3,2,3,6,8}; int *mas = X; ...

Арифметика указателей (указатель на void*)
У меня есть указатель на void*, который я получил с помощью void *beginPointer = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);Мне...

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

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


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru