2010-10-02 99 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