不能將類模板的宣告與實現分開寫
阿新 • • 發佈:2019-02-20
今天用類模型實現一個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;
}