需要注意的问题:类模板无法分开链接问题。
类模板在编译的时候没有错误,但是在链接过程中会报错
error LNK2019: unresolved external symbol "public: __thiscall LinkList<int>::~LinkList<int>(void)" (??1?$LinkList@H@@QAE@XZ) referenced in function _main
这是由于类模板的声明和实现不能放在不同的文件中,即类模板的声明和实现是不能分离的。因为类模板和函数模板都不是真正的定义,真正的定义是在模板实体化的时候由编译器完成的。如果将模板的定义部分和实现部分分离开来,编译器真正要去完成模板实体化的时候就会因为找不到相应的代码而发生链接错误。
1: //linklist.cpp
2: #ifndef LINKLIST_CPP_CPP //为了解决类模板无法分开链接问题,需要include该实现文件,并注意重复包含问题。
3: #define LINKLIST_CPP_CPP
4:
5: #include "linklist.h"
6: #include <iostream>
7:
8: template<class T>
9: LinkList<T>::LinkList()
10: {
11: head = new Node(T);
12: head->next = NULL;
13: }
14:
15: template<class T>
16: LinkList<T>::LinkList(T dataArray[], int n)
17: {
18: Node<T> * currentNode, * newNode;
19: head = new Node<T>;
20: currentNode = head;
21: for(int i = 0; i < n; ++i)
22: {
23: newNode = new Node<T>;
24: newNode->data = dataArray[i];
25: currentNode->next = newNode;
26: currentNode = newNode;
27: }
28: currentNode->next = NULL;
29: }
30:
31: template<class T>
32: LinkList<T>::~LinkList()
33: {
34: Node<T> * ptr, * pTemp;
35: ptr = head;
36: while(ptr)
37: {
38: pTemp = ptr;
39: ptr = ptr->next;
40: delete pTemp;
41: }
42: head = NULL;
43: }
44:
45: template<class T>
46: int LinkList<T>::ListLength()
47: {
48: Node<T> * ptr;
49: int count = 0;
50: ptr = head->next;
51: while(ptr)
52: {
53: ptr = ptr->next;
54: ++count;
55: }
56: return count;
57: }
58:
59: template<class T>
60: T LinkList<T>::GetItem(int pos)
61: {
62: Node<T> * ptr;
63: ptr = head->next;
64: int position = 1;
65: while(ptr && (position < pos))
66: {
67: ptr = ptr->next;
68: ++position;
69: }
70: if(!ptr)
71: {
72: cerr<<"Cannot find the Item."<<endl;
73: exit(1);
74: }
75: else
76: {
77: return ptr->data;
78: }
79: }
80:
81: template<class T>
82: int LinkList<T>::LocateItem(T item)
83: {
84: Node<T> * ptr;
85: ptr = head->next;
86: int position = 1;
87: while(ptr && (ptr->data != item))
88: {
89: ptr = ptr->next;
90: ++position;
91: }
92: if(ptr)
93: {
94: return position;
95: }
96: else
97: {
98: return 0;
99: }
100: }
101:
102: template<class T>
103: void LinkList<T>::PrintLinkList()
104: {
105: Node<T> * ptr;
106: ptr = head->next;
107: while(ptr)
108: {
109: cout<<ptr->data<<endl;
110: ptr = ptr->next;
111: }
112: }
113:
114: template<class T>
115: void LinkList<T>::InsertItem(int pos, T item)
116: {
117: Node<T> * ptr, * pTemp;
118: ptr = head;
119: int position = 1;
120: while(ptr && (position < pos))
121: {
122: ptr = ptr->next;
123: ++position;
124: }
125: if(!ptr)
126: {
127: cerr<<"Cannot insert in this position."<<endl;
128: exit(1);
129: }
130: else
131: {
132: pTemp = new Node<T>;
133: pTemp->data = item;
134: pTemp->next = ptr->next;
135: ptr->next = pTemp;
136: }
137: }
138:
139: template<class T>
140: T LinkList<T>::DeleteItem(int pos)
141: {
142: Node<T> * ptr, * pTemp;
143: T item;
144: ptr = head;
145: int position = 1;
146: while(ptr && (position < pos))
147: {
148: ptr = ptr->next;
149: ++position;
150: }
151: if(!ptr || !ptr->next)
152: {
153: cerr<<"Cannot fine item need to delete in this position."<<endl;
154: exit(1);
155: }
156: else
157: {
158: pTemp = ptr->next;
159: item = pTemp->data;
160: ptr->next = pTemp->next;
161: delete pTemp;
162: return item;
163: }
164: }
165:
166: template<class T>
167: void LinkList<T>::InvertItem()
168: {
169: Node<T> *ptr, *pTemp;
170: ptr = head->next;
171: head->next = NULL;
172: while(ptr != NULL)
173: {
174: pTemp = ptr;
175: ptr = ptr->next;
176: pTemp->next = head->next;
177: head->next = pTemp;
178: }
179: }
180:
181: template<class T>
182: void LinkList<T>::Merge(LinkList<T> &linklist)
183: {
184: Node<T> *p1,*p2,*p3;
185: p1 = this->head->next;
186: p2 = linklist.head->next;
187: p3 = this->head;
188:
189: while((p1 != NULL) && (p2 != NULL))
190: {
191: if(p1->data < p2->data)
192: {
193: p3->next = p1;
194: p1 = p1->next;
195: p3 = p3->next;
196: }
197: else
198: {
199: p3->next = p2;
200: p2 = p2->next;
201: p3 = p3->next;
202: }
203: }
204: if(!p1)
205: {
206: p3->next = p1;
207: }
208: if(!p2)
209: {
210: p3->next = p2;
211: }
212:
213: delete linklist.head;
214: linklist.head = NULL;
215: }
216:
217: #endif
1: //linkList.h
2:
3: #ifndef LINKLIST_H_H
4: #define LINKLIST_H_H
5:
6: //#include <iostream>
7: using namespace std;
8:
9: template<class T>
10: struct Node
11: {
12: T data;
13: Node<T> * next;
14: };
15:
16: template<class T>
17: class LinkList
18: {
19: private:
20: Node<T> * head;
21: public:
22: LinkList();
23: LinkList(T dataArray[], int n);
24: ~LinkList();
25: int ListLength();
26: T GetItem(int pos);
27: int LocateItem(T item);
28: void PrintLinkList();
29: void InsertItem(int pos, T item);
30: T DeleteItem(int pos);
31: void InvertItem();//反转
32: void Merge(LinkList<T> &linklist);//合并
33: };
34:
35:
36: #endif
1: //test.cpp
2:
3: #include "linklist.h"
4: #include "linklist.cpp" //类模板无法分开链接
5: #include <iostream>
6: using namespace std;
7:
8: int main(int argc, char * argv[])
9: {
10: int array1[] = {1,3,5,7,9};
11: int array2[] = {2,4,6,8,10};
12:
13: LinkList<int> linklist(array1,5);
14: LinkList<int> linklist2(array2,5);
15:
16: cout<<"Show all item:"<<endl;
17: linklist.PrintLinkList();
18:
19: cout<<"Length:"<<linklist.ListLength()<<endl;
20:
21: cout<<"The second item is:"<<linklist.GetItem(2)<<endl;
22:
23: cout<<"item 3 is in position:"<<linklist.LocateItem(3)<<endl;
24:
25: cout<<"Insert item 5 in position 4:"<<endl;
26: linklist.InsertItem(4,5);
27: cout<<"Show all item:"<<endl;
28: linklist.PrintLinkList();
29:
30: cout<<"Invert:"<<endl;
31: linklist.InvertItem();
32: cout<<"Show all item:"<<endl;
33: linklist.PrintLinkList();
34:
35: cout<<"Show linklist1:"<<endl;
36: linklist.PrintLinkList();
37: cout<<"Show linklist2:"<<endl;
38: linklist2.PrintLinkList();
39: cout<<"Merge them:"<<endl;
40: linklist.Merge(linklist2);
41: linklist.PrintLinkList();
42:
43: return 0;
44: }