今天用类模型实现一个linklist,开始是.h和.cpp将类模板的声明与实现分开写的,结果总是报错:
摆弄了半个小时都不知道为啥,结果一百度,原来类模板的声明与实现是不能够分开写的。
《C++编程思想》第15章(第300页)说明了原因:
模板定义很特殊。由template<…> 处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。
这里把我的linklist的代码也贴过来好了:
//linklist.h
#pragma once
#ifndef _LINKLIST_H_
#define _LINKLIST_H_
#include<iostream>
using namespace std;
template<typename T>
struct Node {
T t;
struct Node<T>* next;
};
template<typename T>
class linklist {
public:
linklist();
~linklist();
public:
int clear();
int getlength();
int getnode(int pos, T &t);
int insertnode(int pos, T &t);
int deletenode(int pos, T &t);
private:
int m_length;
Node<T>* m_head;
};
template<typename T>
linklist<T>::linklist() {
m_head = new Node<T>;
m_head->next = NULL;
m_length = 0;
}
template<typename T>
linklist<T>::~linklist() {
Node<T> *temp = NULL;
while (m_head) {
temp = m_head->next;
delete m_head;
m_head = temp;
}
}
template<typename T>
int linklist<T>::clear() {
Node<T> *temp = NULL;
while (m_head) {
temp = m_head->next;
delete m_head;
m_head = temp;
}
m_head = new Node<T>;
m_head->next = NULL;
m_length = 0;
return 0;
}
template<typename T>
int linklist<T>::getlength() {
return m_length;
}
template<typename T>
int linklist<T>::getnode(int pos, T &t) {
int ret = 0;
if (pos < 0 || pos > m_length) {
ret = 1;
cout << "func getnode() pos < 0 || pos > m_length err : " << ret << endl;
return ret;
}
Node<T>* current = m_head;
int i = 0;
while (i++ < pos)
current = current->next;
t = current->next->t;
return ret;
}
template<typename T>
int linklist<T>::insertnode(int pos, T &t) {
int ret = 0;
if (pos < 0 || pos > m_length) {
ret = 1;
cout << "func getnode() pos < 0 || pos > m_length err : " << ret << endl;
return ret;
}
Node<T>* current = m_head;
int i = 0;
while (i++ < pos)
current = current->next;
Node<T>* newnode = new Node<T>;
newnode->next = NULL;
newnode->t = t;
newnode->next = current->next;
current->next = newnode;
m_length++;
return ret;
}
template<typename T>
int linklist<T>::deletenode(int pos, T &t) {
int ret = 0;
if (pos < 0 || pos > m_length) {
ret = 1;
cout << "func getnode() pos < 0 || pos > m_length err : " << ret << endl;
return ret;
}
Node<T>* current = m_head;
int i = 0;
while (i++ < pos)
current = current->next;
Node<T>* delnode = current->next;
t = delnode->t;
current->next = delnode->next;
delete delnode;
m_length--;
return ret;
}
#endif
//linklist_cpp_test.cpp
#include<iostream>
#include"linklist.h"
using namespace std;
struct Teacher {
char name[64];
int age;
};
void foo() {
Teacher t1, t2, t3;
Teacher temp;
t1.age = 31;
t2.age = 32;
t3.age = 33;
linklist<Teacher> list;
list.insertnode(0, t1);
list.insertnode(0, t2);
list.insertnode(0, t3);
for (int i = 0; i < list.getlength(); i++) {
list.getnode(i, temp);
cout << "temp.age = " << temp.age << endl;
}
while (list.getlength() > 0) {
list.deletenode(0, temp);
cout << "temp.age = " << temp.age << endl;
}
}
int main() {
foo();
system("pause");
return 0;
}