1. 程式人生 > >不能將類模板的宣告與實現分開寫

不能將類模板的宣告與實現分開寫

今天用類模型實現一個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;
}