Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 31.10.2016
Сообщений: 9
1

Шаблонный дек

21.03.2017, 23:42. Показов 2429. Ответов 5
Метки нет (Все метки)

Задача реализовать шаблонный класс дека, и класс Итератора для навигации по деку. До добавления шаблонов все хорошо работало. Ныне такие страшные ошибки
Кликните здесь для просмотра всего текста
Ошибка 1 error LNK2019: ссылка на неразрешенный внешний символ "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Deque<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01 @ABV?$Deque@H@@@Z) в функции _main
Ошибка 2 error LNK1120: неразрешенных внешних элементов: 1

Сам код
Кликните здесь для просмотра всего текста

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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#include  <iostream>
// D-Очередь в виде простого двунаправленный список с указателем на начало очереди.
using namespace std;
 
template <class T> struct Node
{
    T Data;
    Node<T>* Next;
    Node<T>* Prev;
    Node(T data)
    {
        this->Data = data;
        Next = NULL;
        Prev = NULL;
    }
};
template <class T> class Deque
{
    Node<T> *head;
public:
    int size;
    Deque();
    Deque(const Deque&);
    ~Deque();
    void push_front(T);
    T pop_front();
    void push_back(T);
    T pop_back();
    const T peek();
    const bool isEmpty();
    Deque<T>& operator= (const Deque&);
    friend ostream& operator<< (ostream&, const Deque<T>&);
    template <class T>
    friend class Iterator;
};
template <class T>
class Iterator
{
    Deque<T> *D;
    Node<T> *current;
public:
    // Конструктор преобразования
    Iterator(Deque<T> &obj)
    {
        D = &obj;
        current = obj.head;
    }
    // Возвращает текущий объект дека без его удаления
    int peek(){
        return current->Data;
    }
    // Переходит к следующему объекту дека
    void next(){
        current = current->Next;
    }
    // Переходит к предыдущему объекту дека
    void prev(){
        current = current->Prev;
    }
    // Переходит в начало дека
    void reset(){
        current = D->head;
    }
    // Проверяет существует ли элемент
    const bool isEmptyElement(){
        if (!current)
            return true;
        else
            return false;
    }
    // Доступ к элементу по адресу
    void set(Node<T>*p = 0){
        current = p;
    }
};
// Конструктор по умолачанию
template <class T>
Deque<T>::Deque(){
    head = NULL;
    size = 0;
}
// Конструктор копирования
template <class T>
Deque<T>::Deque(const Deque& obj)
{
    if (!obj.head)
    {
        head = new Node<T>(NULL);
    }
    head = new Node<T>(obj.head->Data);
    Node<T>* temp = obj.head->Next;
    Node<T>* pnew = 0;
    Node<T>* pold = head;
    while (temp)
    {
        pnew = new Node<T>(temp->Data);
        pnew->Prev = pold;
        pold->Next = pnew;
        pold = pnew;
        temp = temp->Next;
    }
}
template <class T>
// Деструктор
Deque<T>::~Deque()
{
    while (!isEmpty())
        pop_front();
}
// Вставляет объект как верхний элемент дека
template <class T>
void Deque<T>::push_front(T data)
{
    size++;
    if (head != NULL)
    {
        Node<T>* temp = new Node<T>(data);
        temp->Next = head;
        head->Prev = temp;
        head = temp;
    }
    else
    {
        head = new Node<T>(data);
    }
}
// Удаляет и возвращает объект, находящийся в начале дека
template <class T>
T Deque<T>::pop_front()
{
    if (head)
    {
        int temp = head->Data;
        Node<T>* p = head;
        head = p->Next;
        delete[] p;
        size--;
        return temp;
    }
    else
        return NULL;
}
// Вставляет объект как нижний элемент дека
template <class T>
void Deque<T>::push_back(T data)
{
    size++;
    if (head != NULL)
    {
        Node<T>* tail = new Node<T>(NULL);
        for (Node<T>*i = head; i != NULL; i = i->Next){
            if (i->Next == NULL)
                tail = i;
        }
        Node<T>* temp = new Node<T>(data);
        tail->Next = temp;
        temp->Prev = tail;
        tail = temp;
    }
    else
    {
        head = new Node<T>(data);
    }
}
// Удаляет и возвращает объект, находящийся в конце дека
template <class T>
T Deque<T>::pop_back()
{
    if (head)
    {
        Node<T>* tail = new Node<T>(NULL);
        for (Node<T>*i = head; i != NULL; i = i->Next){
            if (i->Next == NULL)
                tail = i;
        }
        int temp = tail->Data;
        Node<T>* p = tail;
        tail = p->Prev;
        tail->Next = NULL;
        delete[] p;
        size--;
        return temp;
    }
    else
        return NULL;
}
// Возвращает объект в верхней части дека без его удаления
template <class T>
const T Deque<T>::peek()
{
    if (head)
        return head->Data;
    else
        return 0;
}
// Проверяет пуст ли дек
template <class T>
const bool Deque<T>::isEmpty() {
    return size == 0;
}
// Перегрузка оператора присваивания
template <class T>
Deque<T>& Deque<T>::operator= (const Deque& obj)
{
    if (this == &obj)
        return *this;
    if (!obj.head)
        return *this;
    head = new Node<T>(obj.head->Data);
    Node<T>* temp = obj.head->Next;
    Node<T>* pnew = 0;
    Node<T>* pold = head;
    while (temp)
    {
        pnew = new Node<T>(temp->Data);
        pnew->Prev = pold;
        pold->Next = pnew;
        pold = pnew;
        temp = temp->Next;
    }
    return *this;
}
// Перегрузка потокового поератора вывода
template <class T>
ostream& operator<<(ostream& os, const Deque<T>& obj)
{
    for (Node<T>* i = obj.head; i != NULL; i = i->Next)
        os << i->Data << " ";
    return os;
}
int main()
{
    Deque<int> A, B;
    A.push_front(72);
    A.push_back(42);
    A.push_front(50);
    A.push_back(19);
    A.push_front(30);
    cout << A << endl;
    A.pop_front();
    cout << A << endl;
    A.pop_back();
    cout << A << endl;
    Deque<int> C(A);
    cout << C << endl;
    Iterator<int> I(A);
    I.next();
    I.next();
    cout << I.peek() << endl;
    I.prev();
    cout << I.peek() << endl;
    I.reset();
    cout << I.peek() << endl;
    cout << A << endl;
    B = A;
    cout << B << endl;
    A.~Deque();
    B.~Deque();
    C.~Deque();
    system("pause");
}

Прошу помочь найти ошибку и встать на путь истинный.
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.03.2017, 23:42
Ответы с готовыми решениями:

Шаблонный дек
Доброго времени суток. Пытаюсь написать шаблонный дек, но не получается сделать многофайловый...

Разработать шаблонный класс "дек" на основе односвязного списка
3. Разработать шаблонный класс &quot;дек&quot; на основе односвязного списка. Реализовать операции: ...

дек
как сделать такую вещь? реализовать и протестировать контейнерный класс динамической структуры...

Простой дек
Помогите решить задачу : Реализуйте структуру данных &quot;дек&quot;. Напишите программу, содержащую...

5
281 / 235 / 114
Регистрация: 07.09.2016
Сообщений: 587
22.03.2017, 00:19 2
Лучший ответ Сообщение было отмечено includelowgw как решение

Решение

объявите друга шаблонным:
C++
1
2
3
4
5
    ...
    template <class U>
    friend ostream& operator<< (ostream&, const Deque<U>&);
    //friend ostream& operator<< (ostream&, const Deque<T>&);
    ...
C++
1
2
3
4
 // A это зачем???
 A.~Deque();
 B.~Deque();
 C.~Deque();
Добавлено через 2 минуты
нигде не увидел new [], зато есть
C++
1
       delete[] p;
это ошибка

Добавлено через 2 минуты
еще ошибка:
C++
1
2
3
       int temp = head->Data;
надо
T temp = head->Data;
в той же функции pop_front странный return NULL;
не будет компилиться для Deque<std::string> или чего-нибудь такого не встроенного типа. надо исключение бросать, если нечего вернуть.
1
0 / 0 / 0
Регистрация: 31.10.2016
Сообщений: 9
22.03.2017, 00:20  [ТС] 3
Спасибо большое!

Цитата Сообщение от DU3 Посмотреть сообщение
1
2
3
4
*// A это зачем???
*A.~Deque();
*B.~Deque();
*C.~Deque();
Продемонстрировать явный вызов, заморочка преподавателя)
Цитата Сообщение от DU3 Посмотреть сообщение
нигде не увидел new [], зато есть
C++Выделить код
1
* * * *delete[] p;
это ошибка
Но в в обоих push'aх new имеется
0
281 / 235 / 114
Регистрация: 07.09.2016
Сообщений: 587
22.03.2017, 00:22 4
C++
1
2
3
4
5
6
7
8
template <class T>
const T Deque<T>::peek()
{
    if (head)
        return head->Data;
    else
        return 0; // аналогично предыдущему. почему 0? тут надо исключение бросать.
}
Добавлено через 1 минуту
new есть, а вот new[] нет.
вызывайте delete для того, для чего new был вызван и delete[] для того, для чего вызывали new[]. так вот выделений массивом я не увидел. если они есть - то ок.
1
0 / 0 / 0
Регистрация: 31.10.2016
Сообщений: 9
22.03.2017, 00:25  [ТС] 5
До исключений еще не дорос) Спасибо за поправки.
0
281 / 235 / 114
Регистрация: 07.09.2016
Сообщений: 587
22.03.2017, 00:29 6
препод под явными вызовами деструкторов скорее всего имел другое.
для начала попробуйте собрать свой дек с пользовательским типом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
struct MyClass
{
};
 
Deque<MyClass> myDeq; // добейтесь компилябельности.
 
далее сделайте так, чтобы у этого класса не было конструктора по умолчания. т.е.
struct MyClass
{
   explicit MyClass(int) {};
};
Deque<MyClass> myDeq;
// и вот тут то вам придется подумать и возможно заюзать placement new, а с ним и явные вызовы деструкторов.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.03.2017, 00:29

Дек символов
Доброго времени суток всем. У меня такая проблема: есть задача - Реализовать класс &quot;Дек...

Очередь и дек С++
Ребят, помогите пожалуйста сделать небольшую программу, ну просто горит(((. :wall: Разработать...

Дек-шаблон
Доброй ночи. У меня вопрос. Я хочу реализовать дек, а потом на его основе сделать шаблон. В деке...

Полный дек
Добрый день! мучаюсь с задачей - реализовать тип и функции (инициализация,добавление\извлечение...


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

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

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