为什么在这个C ++类的.o文件中没有定义函数?

时间:2010-11-09 13:55:08

标签: c++ templates linker

我有一个我正在使用的C ++类,并且当我使用`nm --demangle'查看.o文件时,它中没有显示的函数,并且当程序尝试时函数丢失尽管一切都很好。

标题如下:

#ifndef __COLLECTION_H
#define __COLLECTION_H

#include <vector>

#include "ObjectInstance.h"

using namespace std;

template <class T>
class Collection : public ObjectInstance
{       
protected:
    vector<T*> items;
    void internalInsertAt(T* item, int index);
    void internalRemoveIndex(int index);
    void internalRemoveItem(T* item);

public:
    virtual ~Collection();
    // Specific functions for this interface
    static int item(jsplugin_obj *this_obj, jsplugin_obj *function_obj, int argc, 
    T* internalGetItem(int index);
    int getSize();
    void addItem(T* item);
};

#endif

并且addItem函数实现为

template <class T>
void Collection<T>::addItem(T* item)
{   
    items.push_back(item);
}   

我得到的错误是当我尝试在另一个类中继承此类并在运行时显示时:undefined symbol: _ZN10CollectionIN4NJSE5TrackEE7addItemEPS1_

我觉得我在这里缺少一些简单的东西,但不知道它是什么。

4 个答案:

答案 0 :(得分:3)

函数是头文件还是源文件?处理模板的最简单方法是将所有模板定义放在头文件中,以保证定义可用于实例化它的任何代码。

答案 1 :(得分:3)

嗯,我认为这是因为该函数是模板的成员。在C ++中,您无法编译模板(至少不容易)。如果要分发模板类,请在标题中写下所有代码。

答案 2 :(得分:2)

编译器需要访问addItem的整个模板定义(而不仅仅是签名)才能为模板的每个实例化生成代码,因此您需要将其定义移动到标题中,即关注inclusion model

事实上,现代C ++编译器不容易支持模板的单独编译模型。

答案 3 :(得分:2)

单独的编译单元中的模板可能是一场噩梦,需要严重的编译器繁重。

请记住,必须为您尝试实例化模板的每个类型T编译特定版本的模板函数。

因此,最简单的方法是将所有模板函数定义放入“.h”头文件中。