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

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

Войти
Регистрация
Восстановить пароль
 
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
#1

Не получается сделать 3 класса шаблонными. - C++

25.09.2011, 17:13. Просмотров 424. Ответов 6
Метки нет (Все метки)

Есть три класса + функция main, в которой используются эти классы. Все работает.
Сделал эти три класса шаблонными. В main в объявлении дописал <тип>. Но программа не работает.
Если не использовать классы в main, то программа запускается.
Ошибки такие:
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: __thiscall List<int>::~List<int>(void)" (??1?$List@H@@QAE@XZ)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: int & __thiscall Iterator<int>::operator[](int)" (??A?$Iterator@H@@QAEAAHH@Z)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: int & __thiscall Iterator<int>::operator*(void)" (??D?$Iterator@H@@QAEAAHXZ)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: bool __thiscall Iterator<int>::operator!=(class Iterator<int> const &)" (??9?$Iterator@H@@QAE_NABV0@@Z)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: class Iterator<int> __thiscall List<int>::end(void)const " (?end@?$List@H@@QBE?AV?$Iterator@H@@XZ)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: class Iterator<int> & __thiscall Iterator<int>::operator++(void)" (??E?$Iterator@H@@QAEAAV0@XZ)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: class Iterator<int> __thiscall List<int>::begin(void)const " (?begin@?$List@H@@QBE?AV?$Iterator@H@@XZ)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: class List<int> const & __thiscall List<int>::operator=(class List<int> const &)" (??4?$List@H@@QAEABV0@ABV0@@Z)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: __thiscall List<int>::List<int>(class List<int> const &)" (??0?$List@H@@QAE@ABV0@@Z)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: bool __thiscall List<int>::isEmpty(void)const " (?isEmpty@?$List@H@@QBE_NXZ)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: bool __thiscall List<int>::remove(int &)" (?remove@?$List@H@@QAE_NAAH@Z)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class List<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$List@H@@@Z)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: void __thiscall List<int>::insert(int,int)" (?insert@?$List@H@@QAEXHH@Z)"
1>main.obj : error LNK2001: неразрешенный внешний символ ""public: __thiscall List<int>::List<int>(void)" (??0?$List@H@@QAE@XZ)"
1>D:\....exe : fatal error LNK1120: 14 неразрешенных внешних элементов
Вот .h файлы класса, ибо я думаю достаточно на них посмотреть, чтобы понять, почему ошибка
+ main. Определения методов я выложу ниже.
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
#ifndef NODE_H
#define NODE_H
 
#include <iostream>
 
class Node
{
    friend class List;
    friend class Iterator;
    friend std::ostream &operator<<( std::ostream &, const List &);
 
public:
    Node( int, int); // конструктор инициализации key, data и nextPtr
private:
    int key;
    int data;
    Node *nextPtr;
};
 
#endif
#ifndef LIST_H
#define LIST_H
 
#include <iostream>
#include "Node.h"
#include "Iterator.h"
 
class List
{
    friend std::ostream &operator<<( std::ostream &, const List &);
 
public:
    List();
    List( const List & );
    ~List();
 
    void insert( int, int ); //вставка элемента в список с данными key и data
    bool remove( int & ); // возвращение элемента по ссылке с минимальным ключом и удаление этого элемента
    bool isEmpty() const; // проверка отсутствия элементов
    int peek() const; // возвращает данные в начале очереди
    Iterator begin() const; 
    Iterator end() const; 
    const List &operator=( const List & );
 
private:
    Node *firstPtr;
    Node *lastPtr;
    
    Node *getNewNode( int, int ); // выделиние памяти для нового элемента с данными key и data
};
 
#endif
#ifndef ITERATOR_H
#define ITERATOR_H
 
#include "Node.h"
 
class Iterator
{
public:
    Iterator( Node * ); // конструктор получает указатель на первый элемент
 
    int operator*() const; // перегрузка операции * для rvalue
    int &operator*(); // перегрузка операции * для lvalue
    int operator[]( int ) const; // перегрузка операции [] для rvalue
    int &operator[]( int ); // перегрузка операции [] для lvalue
    Iterator &operator++(); // перегрузка префиксной операции ++
    Iterator operator++( int ); // перегрузка постфиксной операции ++
    bool operator==( const Iterator & ); // перегрузка отношении ==
    bool operator!=( const Iterator & ); // перегрузка отношении !=
 
private:
    Node *nodePtr; // указатель на текущий элемент списка
};
#endif
#include <iostream>
#include "Node.h"
#include "List.h"
#include "Iterator.h"
 
int main()
{
    setlocale( LC_ALL, "rus" );
    List< int > list;
 
    std::cout << "Добавим 7 элементов в очередь и выведем весь список.\nlist = \n";
    list.insert(3,3);
    list.insert(1,10);
    list.insert(9,8);
    list.insert(2,4);
    list.insert(7,11);
    list.insert(3,5);
    list.insert(8,21);
    list.insert(4,5);
    std::cout << list;
    
    std::cout << "Удалим из очереди 4 элемента с наименьшими ключами и выведем эти элементы.\ndata = ";
    int data = 0;
    list.remove(data);
    std::cout << data << ", ";
    list.remove(data);
    std::cout << data << ", ";
    list.remove(data);
    std::cout << data << ", ";
    list.remove(data);
    std::cout << data << std::endl;
    
    std::cout << "Проверим пуст ли список.\nlist.isEmpty() = " << std::boolalpha
        << list.isEmpty() << std::endl;
 
    std::cout << "Проверим работу конструктора копирования.\nList list2(list);\nlist2 = " << std::endl;
    List< int > list2(list);
    std::cout << list2;
 
    std::cout << "Проверим работу перегруженной операции присваивания.\nList list3;\nlist3 = list;\nlist3 = \n";
    List< int > list3; 
    list3 = list;
    std::cout << list3;
 
    std::cout << "Теперь проверим работу итератора." << std::endl 
        << "Проверим перегружунные операции * для lvlaue и rvalue.\n*it = "; 
 
    int i = 1;
    for( Iterator< int > it = list.begin(); it != list.end(); ++it )
    {
        *it = 10*i;
        ++i;
        std::cout << *it << ' ';
    }
    std::cout << std::endl;
 
    std::cout << "Проверим перегружунные операции [] для lvalue и rvalue.\nit[j] = ";
    Iterator< int > it = list.begin();
    for( int j = 0; j < 4 ; ++j )
    {
        it[j] = j+5;
        std::cout << it[j] << ' ';
    }
    std::cout << std::endl;
 
    system("pause");
    return 0;
}
Определения методов:
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
#include "Node.h"
 
template < class T >
Node< T >::Node( T m_key, T m_data )
:key( m_key ), data( m_data ), nextPtr(0)
{
}
#include "List.h"
#include "Iterator.h"
#include <iostream>
#include <iomanip>
 
template < class T >
List< T >::List()
:firstPtr(0), lastPtr(0)
{
}
template < class T >
List< T >::List( const List< T > &list )
:firstPtr(0), lastPtr(0)
{
    Node *currentPtr = list.firstPtr;
    while( currentPtr != 0 )
    {
        insert( currentPtr->key, currentPtr->data );
        currentPtr = currentPtr->nextPtr;
    }
}
template < class T >
List< T >::~List()
{
    if( !isEmpty() )
    {
        Node *currentPtr = firstPtr;
        Node *tempPtr;
 
        while( currentPtr != 0 )
        {
            tempPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
            delete tempPtr;
        }
    }
}
template < class T >
void List< T >::insert( T m_key, T m_data )
{
    Node *newPtr = getNewNode( m_key, m_data );
 
    if( isEmpty() )
        firstPtr = lastPtr  = newPtr;
    else if( firstPtr->key > newPtr->key ) 
    {
        newPtr->nextPtr = firstPtr;
        firstPtr = newPtr;
    }
    else if( lastPtr->key <= newPtr->key )
    {
        lastPtr->nextPtr = newPtr;
        lastPtr = newPtr;
    }
    else 
    {
        Node *currentPtr = firstPtr;
        Node *previousPtr = currentPtr;
        while( currentPtr != 0 && currentPtr->key <= newPtr->key )
        {
            previousPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
        }
        previousPtr->nextPtr = newPtr;
        newPtr->nextPtr = currentPtr;
    }
}
template < class T >
bool List< T >::remove( T &m_data )
{
    if( !isEmpty() )
    {
        Node *tempPtr = firstPtr;
        firstPtr = firstPtr->nextPtr;
        m_data = tempPtr->data;
        delete tempPtr;
        return true;
    }
    return false;
}
template < class T >
bool List< T >::isEmpty() const
{
    return firstPtr == 0;
}
template < class T >
Node< T > *List< T >::getNewNode( T m_key, T m_data)
{
    return new Node( m_key, m_data );
}
template < class T >
std::ostream &operator<<( std::ostream &output, const List< T > &list )
{
    std::cout << std::setw(10) << "key" << std::setw(10) << "data" << std::endl;
    Node *currentPtr = list.firstPtr;
    while( currentPtr != 0 )
    {
        std::cout << std::setw(10) << currentPtr->key
            << std::setw(10) << currentPtr->data << std::endl;
        currentPtr = currentPtr->nextPtr;
    }
    return output;
}
template < class T >
const List< T > &List< T >::operator=(const List< T > & right)
{
    if( this != &right ) // проверка на самоприсваивание
    {
        this->List::~List();
        this->List::List( right );
        return *this;
    }
    return *this;
}
template < class T >
Iterator< T > List< T >::begin() const
{
    return Iterator( firstPtr );
}
template < class T >
Iterator< T > List< T >::end() const
{
    return Iterator( 0 );
}
template < class T >
T List< T >::peek() const
{
    return (( firstPtr != 0 ) ? firstPtr->data : 0 );
}
#include "Iterator.h"
#include <iostream>
 
template < class T >
Iterator< T >::Iterator( Node< T > * m_nodePtr )
: nodePtr( m_nodePtr )
{
}
template < class T >
T Iterator< T >::operator*() const
{
    return nodePtr->data;
}
template < class T >
T &Iterator< T >::operator*()
{
    return nodePtr->data;
}
template < class T >
Iterator< T > &Iterator< T >::operator++()
{
    nodePtr = nodePtr->nextPtr;
    return *this;
}
template < class T >
Iterator< T > Iterator< T >::operator++( int )
{
    Iterator temp( nodePtr );
    nodePtr = nodePtr->nextPtr;
    return temp;
}
template < class T >
bool Iterator< T >::operator==( const Iterator< T > &right )
{
    return nodePtr == right.nodePtr;
}
template < class T >
bool Iterator< T >::operator!=( const Iterator< T > &right )
{
    return !(*this == right );
}
template < class T >
T Iterator< T >::operator[]( int subscript ) const
{
    Node *currentPtr = nodePtr;
    int i = 0;
    while( currentPtr != 0 )
    {
        if( i == subscript )
            return currentPtr->data;
        ++i;
        currentPtr = currentPtr->nextPtr;
    }
    std::cout << "Ошибка: выход за границу списка." << std::endl;
    system("pause");
    exit(1);
}
template < class T >
T &Iterator< T >::operator[]( int subscript )
{
    Node *currentPtr = nodePtr;
    int i = 0;
    while( currentPtr != 0 )
    {
        if( i == subscript )
            return currentPtr->data;
        ++i;
        currentPtr = currentPtr->nextPtr;
    }
    std::cout << "Ошибка: выход за границу списка." << std::endl;
    system("pause");
    exit(1);
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.09.2011, 17:13     Не получается сделать 3 класса шаблонными.
Посмотрите здесь:

При перегрузке оператора для класса не получается использовать имя переменной такое же, как в описании класса - C++
Описал первый класс,затем - описал второй класс, используя первый,и когда начал перезагружать оператор для второго класса, вылезла...

Не работает программа с шаблонными функциями - C++
Дана целочисленная прямоугольная матрица . Напишите программу, определяющую величины: 1) количество элементов матрицы, меньших величины...

typename. Проблемы с вложенными шаблонными типами - C++
Здравствуйте. Реализовываю шаблонный список. /* * List.h */ #pragma once #include &lt;iostream&gt; using namespace std;

Создать единый класс с шаблонными векторами - C++
Здравствуйте, уважаемые. Возник 1 вопрос при написании шаблонного класса: как сделать так, чтоб при создании объекта класса конструктор...

Не получается отсортировать по полю класса - C++
Здравствуйте! Не понимаю, в чем ошибка. Есть вектор, содержащий указатели на объекты класса Shape Хочу его отсортировать с помощью...

Не получается создать массив класса - C++
#include &lt;iostream&gt; using namespace::std; class dvig { friend void sum_all(dvig &amp;,dvig &amp;); public: dvig(long double ,long...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
sandye51
программист С++
681 / 583 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
25.09.2011, 17:15     Не получается сделать 3 класса шаблонными. #2
в шаблонных классах нельзя разделять реализацию и интерфейс на .h и .cpp
либо тогда подключать .cpp файлы вместо .h, но это не есть хорошо

и кстати, я чето не вижу чтобы у тебя классы были помечены как шаблонные. Надо писать
C++
1
2
3
4
5
template <typename T>
class list
{
...
};
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
25.09.2011, 17:21     Не получается сделать 3 класса шаблонными. #3
Цитата Сообщение от sandye51 Посмотреть сообщение
и кстати, я чето не вижу чтобы у тебя классы были помечены как шаблонные. Надо писать
Можно писать хоть template <typename T> хоть template <class T>, ничего от этого не меняется.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
25.09.2011, 18:23  [ТС]     Не получается сделать 3 класса шаблонными. #4
Я не то выложил. Положу все определения в h файл, скажу результат и выложу свои шаблонные классы.
Все сделал, только теперь другая ошибка:
1>main.obj : error LNK2001: неразрешенный внешний символ ""class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class List<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$List@H@@@Z)"
1>D:\.exe : fatal error LNK1120: 1 неразрешенных внешних элементов
В main есть такое:
C++
1
2
3
4
5
6
7
8
9
10
List< int > list;
list.insert(3,3);
list.insert(1,10);
list.insert(9,8);
list.insert(2,4);
list.insert(7,11);
list.insert(3,5);
list.insert(8,21);
list.insert(4,5);
std::cout << list;
Если это убрать, то ошибка пропадает.
Определение перегрузки операции << вот :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template < class T >
std::ostream &operator<<( std::ostream &output, const List< T > &list )
{
    std::cout << std::setw(10) << "key" << std::setw(10) << "data" << std::endl;
    Node< T > *currentPtr = list.firstPtr;
    while( currentPtr != 0 )
    {
        std::cout << std::setw(10) << currentPtr->key
            << std::setw(10) << currentPtr->data << std::endl;
        currentPtr = currentPtr->nextPtr;
    }
    return output;
}
Добавлено через 11 минут
Подключенные библиотеки:
C++
1
2
#include <iostream>
#include <iomanip>
sandye51
программист С++
681 / 583 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
25.09.2011, 18:51     Не получается сделать 3 класса шаблонными. #5
Цитата Сообщение от Gepar Посмотреть сообщение
Можно писать хоть template <typename T> хоть template <class T>, ничего от этого не меняется
а я разве утверждал что меняется?
Gepar
26.09.2011, 00:43
  #6

Не по теме:

Цитата Сообщение от sandye51 Посмотреть сообщение
а я разве утверждал что меняется?
Я в первый файл не посмотрел что он там и правда не обозначил классы шаблонными, я думал Вас во втором файле смущает форма template < class T > вместо template <typename T> .

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.09.2011, 01:04     Не получается сделать 3 класса шаблонными.
Еще ссылки по теме:

Не получается заполнить вектор объектами класса - C++
Здравствуйте. Решения для своей проблемы на форуме не нашел, по этому пришлось создать тему. Есть класс: class CAnimate { private: ...

Не получается создать template для класса - C++
Здравствуйте, делаю все, как написано в Интернете, а у меня вылетает ошибка runtime - unresolved externals. Не могу создать правильно...

Не получается создать экземпляр абстрактного класса - C++
в общем я очень тупой, буду благодарен за умные советы, имеется класс object и наследуемые от него triangle и uravn вот фрагмент из мэйна ...

Не получается создать специализацию шаблона класса - C++
Подскажите пожалуйста в чем ошибка. Я гуглил по кодам ошибок, но не смог понять в чем дело. Заголовочный файл: #ifndef ARRAY_H ...


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

Или воспользуйтесь поиском по форуму:
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
26.09.2011, 01:04  [ТС]     Не получается сделать 3 класса шаблонными. #7
Все, заработало.
Yandex
Объявления
26.09.2011, 01:04     Не получается сделать 3 класса шаблонными.
Ответ Создать тему
Опции темы

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