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

Двухсвязный список и оператор [] - C++

Восстановить пароль Регистрация
 
DWand
 Аватар для DWand
13 / 13 / 1
Регистрация: 23.04.2011
Сообщений: 99
10.09.2011, 01:35     Двухсвязный список и оператор [] #1
Здравствуйте!
Очень нужна помощь, так как 4 часа поисков в интернете не дали конкретных результатов.
Я в целях обучения/тренировки пытаюсь создать шаблонный класс, который бы реализовывал бы подобие массива при помощи двухсвязного линейного списка.
Проблема возникла на моменте перегрузки оператора []. Он прекрасно работает по принципу get метода индексаторов из C#, но ругается при попытках использовать его для установки значения.
Помогите, пожалуйста, разобраться в чем ошибка и как ее правильно решить.

Вот исходники:
inc.h
C++
1
2
3
#pragma once
#include <iostream>
using namespace std;
dwList.h
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#pragma once
namespace DW {
 
/* ----------- ОБЬЯВЛЕНИЕ ----------- */
 
template <typename T>
struct Member {
 Member* prev;
 Member* next;
 T value;
};
 
template <typename T>
class dwList {
private:
 Member<T>* start;
 Member<T>* finish;
 
 int length;
 
private:
 Member<T>* NewMember(T value);
 void DeleteByIndex(int index);
 
public:
 dwList();
 ~dwList();
 
public:
 T &operator[] (unsigned int n);
 int Length() const;
 void Clear();
 
 void Append(T value);
};
 
 
 
 
 
 
/* ----------- РЕАЛИЗАЦИЯ ----------- */
 
 
// конструктор
template <typename T>
dwList<T>::dwList() {
 start = NULL;
 finish = NULL;
 
 length = 0;
}
 
 
// деструктор
template <typename T>
dwList<T>::~dwList() {
 Clear();
}
 
 
// вернуть длинну списка
template <typename T>
int dwList<T>::Length() const {
 return length;
}
 
 
// создание нового узла списка
template <typename T>
Member<T>* dwList<T>::NewMember(T value){
 Member<T>* element = new Member<T>;
 element -> prev = NULL;
 element -> next = NULL;
 element -> value = value;
 return element;
}
 
 
// удалить элемент по индексу
template <typename T>
void dwList<T>::DeleteByIndex(int index){
 if (index < 0 || index > length -1) return;
 
 /*
  TODO:
  Обработка: от конца или от начала считать.
  Обработка 2: идти от передвижного указателя
 */
 
 Member<T>* tmp = start;
 int i = 0;
 while (i != index) {
  tmp = tmp -> next;
  i++;
 }
 
 if (tmp == start) start = tmp -> next;
 else if (tmp == finish) finish = tmp -> prev;
 
 if (tmp -> prev != null) tmp -> prev -> next = tmp -> next;
 if (tmp -> next != null) tmp -> next -> prev = tmp -> prev;
 
 /*
  TODO:
  Обработка передвижного указателя: перемещение, изменение индекса
 */
 
 delete tmp;
 length--;
}
 
 
// очистить список
template <typename T>
void dwList<T>::Clear() {
 if (length == 0) return;
 
 Member<T>* tmp = finish;
 while (tmp != NULL) {
  finish = tmp -> prev;
  delete tmp;
  tmp = finish;
 }
 delete tmp;
 start = NULL;
 finish = NULL;
 length = 0;
}
 
 
// добавить элемент в конец списка
template <typename T>
void dwList<T>::Append(T value) {
 Member<T>* newNode = NewMember(value);
 if (start == NULL) {
  start = newNode;
  finish = newNode;
 } else {
  newNode -> prev = finish;
  finish -> next = newNode;
  finish = newNode;
 }
 length++;
}
 
template <typename T>
T &dwList<T>::operator[] (unsigned int n) {
 if (n >= length) return NULL;
 
 int index = 0;
 Member<T>* node = start;
 while (index != n) {
  node = node -> next;
  index++;
 }
 
 return node -> value;
}
 
}
entryPoint.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "inc.h"
#include "dwList.h"
using namespace DW;
 
void main() {
 dwList<int> test;
 test.Append(1);
 test.Append(2);
 cout << test.Length() << endl;
 cout << test[0] << endl;
 test[0] = 3;
 cout << test[0] << endl;
}
P.S.: До этого ни разу с шаблонами не работал и такого рода перегрузки не делал.
Вот что выдает MS Visual Studio 2010 при попытке скомпилировать этот код:
dwlist.h(149): error C2440: 'return' : cannot convert from 'int' to 'int &'

Как get работает если убрать амперсанд перед operator
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.09.2011, 01:35     Двухсвязный список и оператор []
Посмотрите здесь:

C++ Двухсвязный Кольцевой Список
C++ символьный двухсвязный список
C++ Двухсвязный Список
C++ перевернуть двухсвязный линейный список
двухсвязный список C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
10.09.2011, 01:51     Двухсвязный список и оператор [] #2
Ссылки не могут быть null (т.е.указывать в никуда)
Но, несомненно, следует поискать более авторитетный источник
DWand
 Аватар для DWand
13 / 13 / 1
Регистрация: 23.04.2011
Сообщений: 99
10.09.2011, 01:55  [ТС]     Двухсвязный список и оператор [] #3
На сколько я знаю, NULL указывает на участок, адрес которого состоит из одних нулей.
Добавил: но все возможно. Я только учусь и не могу сказать точно... ((
Мое понимание проблемы заключается в том, что я в return пытаюсь вернуть значение, а не ссылку на поле. Но всяческие вариации с * и & в строке возврата результатов особо не дали (
Как сделать правильно? Возможно нужно поменять как-то саму структуру?
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
10.09.2011, 02:10     Двухсвязный список и оператор [] #4
Ну я всего лишь сказал, что ссылка не может быт NULL, в остальное не вникал. Так-то да, не совсем хорошая ситуация, функция сработала некорректно, а ЛЮБОЕ возвращённое значение будет восприниматься программой как корректное.

Но с другой стороны, мы же не жужжим на компилятор, который не ругается на:
C++
1
2
int array [10];
array [15]= 28;
Может стоит возвращать структуру из двух полей- непосредственно ссылки и флага, указывающего на то, корректная ссылка или нет? И тогда ориентироваться исключительно на флаг, но не на ссылку. А вот если он будет true, тогда ссылку считать корректной, а если false, тогда считать некорректной, на что бы она не указывала. Больше ничё в голову не лезет .
DWand
 Аватар для DWand
13 / 13 / 1
Регистрация: 23.04.2011
Сообщений: 99
10.09.2011, 02:20  [ТС]     Двухсвязный список и оператор [] #5
Слушайте, Вы гений! Я на столько увлекся своим кодом, что не понял с первого раза даже сути того, о чем вы написали.

Заменил вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template <typename T>
T &dwList<T>::operator[] (unsigned int n) {
    if (n >= length) throw 1;
 
    int index = 0;
    Member<T>* node = start;
    while (index != n) {
        node = node -> next;
        index++;
    }
 
    return node -> value;
}
и действительно теперь все работает. Единственное, что было бы не плохо разработать класс для ошибки или что-то готовое найти как использовать )))

Добавил:
А можно еще поступить по-другому: расширять массив до нужного количества индексов и получится что-то похожее на РНР ))
Теперь даже свобода творчества появилась ))))
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
10.09.2011, 02:25     Двухсвязный список и оператор [] #6
охренеть) щас сидел думал думал...
а тут оказывается он NULL к int& не может привести))

DWand, ну вообще принято делать оператор[] без проверки диапазона, но в вашем случае можно и сделать...
и уж для чистоты совести length < 0 проверяйте


unsigned не заметил... это ответ на пост ниже
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.09.2011, 02:31     Двухсвязный список и оператор []
Еще ссылки по теме:

C++ двухсвязный список
C++ двухсвязный список
C++ Добавление элементов в двухсвязный список

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

Или воспользуйтесь поиском по форуму:
DWand
 Аватар для DWand
13 / 13 / 1
Регистрация: 23.04.2011
Сообщений: 99
10.09.2011, 02:31  [ТС]     Двухсвязный список и оператор [] #7
По логике пользователь не имеет прямого доступа к length - только чтение.
А unsigned вроде не должен давать ввести отрицательное число.
Хотя даже не знаю. Нужно сидеть разбираться со всем этим еще )))
Главное, что дело сдвинулось в нужном направлении ))
Yandex
Объявления
10.09.2011, 02:31     Двухсвязный список и оператор []
Ответ Создать тему
Опции темы

Текущее время: 08:59. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru