2010-10-02 181 views
3

我想實現一個使用堆作爲基類的左樹。以下是heap.h的內容:C++繼承問題

template <class T> 

class heap { 
public: 
    virtual void init(T*) = 0; 
    virtual void insert(T*) = 0; 
    virtual T delete_min() = 0; 
}; 

以下是leftist.cpp的內容:

#include "heap.h" 

template <class T> 
class leftist_tree : public heap<T> { 
private: 
    T* root; 
public: 
    void init(T* a) {} 
    void insert(T* a) {} 
    T delete_min() {T a; return a;} 
}; 

我使用的是下面的定義通過另一個類leftist_node作爲參數傳遞給這個類:

leftist_tree<leftist_node> mytree; 

我正在爲函數init,insert和delete_min得到一個LNK 2001無法解析的外部符號錯誤。我究竟做錯了什麼?

編輯:

好吧,我在這一點上已經給出的例子是過於複雜。我試圖在較小的範圍內重現相同的錯誤,以便有人可以更容易地識別問題。我創建了以下示例文件。

try.cpp

#include "stdafx.h" 
#include "myclass.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    myclass<int> a; 
    a.hello(3); 
    return 0; 
} 

myclass.h

template <class T> 

class myclass { 
public: 
    void hello(T); 
}; 

myclass.cpp

#include "myclass.h" 
#include <iostream> 
using namespace std; 

template <class T> 
void myclass<T>::hello(T a){ 
    cout<<a<<endl; 
    system("pause"); 
} 

我得到類似的錯誤消息:

1> try.obj :錯誤LNK2001:無法解析的外部符號l「public:void __thiscall myclass :: hello(int)」(?hello @?$ myclass @ H @@ QAEXH @ Z) 1> c:\ users \ meher和\ documents \ visual studio 2010 \ Projects \ try \ Debug \ try.exe:致命錯誤LNK1120:1個未解析的外部設備

你能告訴我現在我哪裏出錯了嗎?由於

+0

沒有解決方案的工作。令人驚訝的是,當我沒有從堆繼承(只是將它聲明爲類leftist_tree {...}),我沒有得到任何編譯錯誤。 – Anand 2010-10-02 01:14:18

+0

我似乎無法重現錯誤。什麼是'leftist_node'?是你的第三個代碼塊,mytree的定義,在與'leftist.cpp'相對應的編譯單元中? – SingleNegationElimination 2010-10-02 01:21:19

+0

始終將模板代碼放在頭文件中。在這種情況下,你在leftist.cpp中顯示的內容應該在leftist.h中。此外,你的leftist_tree聲明拋棄了'heap'方法的'virtual',所以確保你不要試圖在'leftist'的子類中「覆蓋」這些方法,否則會變得怪異。 – 2010-10-02 02:36:13

回答

3

模板功能從正則函數處理過的稍有不同。編譯器在您嘗試使用它之前不會實際編譯該函數。如果您嘗試使用它的唯一地方是.cpp,而函數的主體未定義,那麼它假定它必須在其他位置編譯,併爲鏈接器稍後填入參考。

在你的情況下,你定義了leftist.cpp函數的主體,但是你沒有在那裏使用它,你在別的地方使用它。如果你已經在.h文件中定義了它,那麼這個定義在你試圖使用它的任何地方都可用,並且一切都會好起來的。如果你已經使用了leftist.cpp中的某個函數,那麼這些函數就會被創建,並且鏈接器會修復所有的東西。

一般規則是定義頭文件中所有模板函數的主體。

+0

非常感謝。今天學了點兒新東西。 :) – Anand 2010-10-02 03:57:06

1

只要看到這個錯誤

錯誤LNK20XX解析外部符號

這意味着,當鏈接鏈接器無法找到函數定義。在你的情況下,它是錯誤

希望這可以幫助你。 讓我知道如果你需要更多的幫助

PK

+0

這是正確的,直到主要功能的一部分。他們有一個主要的或者是一個圖書館。該錯誤特別列出了它找不到的功能。 – 2010-10-02 01:05:35

+0

非常感謝我更新了這篇文章。 – Pavan 2010-10-02 01:08:54

3

模板沒有實例化的類型。最簡單的方法是從編譯中刪除.cpp,並將其包含到使用模板的cpp中。

另一個簡單的答案是在.h中定義整個模板。

1

以下應該工作(測試使用g ++):

// File: heap.hh -------------------------- 
template <class T> 
class heap { 
public:a 
    virtual void init(T*) = 0; 
    virtual void insert(T*) = 0; 
    virtual T delete_min() = 0; 
}; 

// File: leftist_tree.hh ------------------ 
#include "heap.hh" 
template <class T> 
class leftist_tree : public heap<T> { 
private: 
    T* root; 
public: 
    void init(T*) {} 
    void insert(T*) {} 
    T delete_min() {T a; return a;} 
}; 

// File: leftist_node.hh ------------------ 
struct leftist_node { 
    int value; 
}; 

// File: leftist_main.cpp ----------------- 
#include "leftist_tree.hh" 
#include "leftist_node.hh" 

int main() { 
    leftist_tree<leftist_node> mytree; 
} 
+0

可能希望將'leftist_node'設爲'struct',以便您可以訪問其成員。 – 2010-10-02 02:32:21

+0

@Mike DeSimone:好的建議,謝謝你提到這一點。編輯做出改變。 – Arun 2010-10-02 02:45:33