【问题标题】:"undefined reference" to a template class function对模板类函数的“未定义引用”
【发布时间】:2010-12-06 16:13:01
【问题描述】:

我正在为一个对象数组编写一个模板类,称为arrayobjclass,它保存指向其他对象的指针,特别是在我的实现中指向其他数组的指针。数组也被实现为对象,称为arrayclass。 正在寻找只需少量更改即可编译。

当我尝试使用以下行测试我的课程时,

g++ main.cpp arrayclass.cpp arrayobjclass.cpp -o arrayobj

我收到以下错误:

/tmp/ccEpROXj.o(.text+0x17c): In function `main':
: undefined reference to `arrayobjclass<arrayclass, int>::arrayobjclass(int)'
/tmp/ccEpROXj.o(.text+0x1dc): In function `main':
: undefined reference to `arrayobjclass<arrayclass, int>::addelem(arrayclass*)'
collect2: ld returned 1 exit status

我真的不明白出了什么问题。任何帮助,将不胜感激。如果有帮助,代码的简短相关部分如下。提前致谢!

这是我的主要内容:

#include "arrayclass.h"
#include "arrayobjclass.h"
#include <iostream>

// 5 arrays of 10 maxsize each
#define MAXSIZE_array 10
#define NUMB_objs 5

using namespace std;

int main () {

    //create a simple array as an arrayclass object
    arrayclass * numbers1 = new arrayclass (MAXSIZE_array);

    //array of objects to hold pointers to simple arrays as created above
    arrayobjclass<arrayclass,int> * myobjs = new arrayobjclass<arrayclass,int> (NUMB_objs);

    //fill up the simple array
    int i;
    for (i=0; i<10; i++) {
        numbers1->addelem(i); 
    }

    //add a pointer to the simple array in my array of objects
    myobjs->addelem(numbers1);    
}

//arrayobjclass.h
//declarations of an array of pointers to objects

template <class obj, class key>
class arrayobjclass {

private:
    //obj * arrayptr;
    obj * objarray [];
    int maxsize;
    int totalelem;
public:
    arrayobjclass(int);
    bool addelem(obj *);
};

//arrayobjclass.cpp
//implementation of arrayobjclass, array of pointers to objects

#include "arrayobjclass.h"
#include "arrayclass.h"

template <class obj,class key>
arrayobjclass<obj,key>::arrayobjclass (int size){    
    maxsize=size;
    objarray = new obj[maxsize];
    totalelem = 0;
}

template <class obj, class key>
bool arrayobjclass<obj,key>::addelem (obj * newobj) {   
    if (totalelem < maxsize ) {
        objarray[totalelem] = newobj;
        totalelem ++;
        return true;
    }
    return false;
}

//arrayclass.h

class arrayclass {

private:
    int * arrayptr;
    int maxsize;
    int totalelem;
public:
    arrayclass(int);
    bool addelem(int);
};

//arrayclass.cpp

#include "arrayclass.h"

arrayclass::arrayclass (int size){   
    maxsize=size;
    arrayptr = new int[maxsize];
    totalelem = 0;
}

bool arrayclass::addelem (int addval) {    
    if (totalelem < maxsize ) {
        arrayptr[totalelem] = addval;
        totalelem ++;
        return true;
    }
    return false;
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    您不能像这样将模板声明放在 .cpp 文件中。模板声明和实现需要在同一个翻译单元中可见。将模板实现放在您直接#include 的标头中。

    【讨论】:

    • 大师,相同的代码在 Gcc 3.1.2 中可编译,但在 4.1.1 中不可编译。我在哪里可以找到他们在编译器中所做的更改,使其不接受 GCC 4.1.1
    【解决方案2】:

    在标题中定义您的函数模板。编译器需要看到它们。

    干杯,

    【讨论】:

    • @downvoter:请解释您的反对意见,以便其他人可以看到为什么您的反对意见很愚蠢。
    【解决方案3】:

    因为模板是在需要时编译的,所以这会强制 多文件项目的限制:实现(定义) 模板类或函数的名称必须与其在同一个文件中 宣言。这意味着我们不能将接口分开 单独的头文件,并且我们必须同时包含接口和 在使用模板的任何文件中实现。

    来自http://www.cplusplus.com/doc/tutorial/templates/

    【讨论】:

    • -1 “模板类或函数的实现(定义)必须与其声明在同一个文件中。”,这是不正确的。那么“这意味着我们不能在单独的头文件中分离接口”又是不正确的。只有最后一个“我们必须在使用模板的任何文件中同时包含接口和实现”。 (在实践中)是正确的,尽管可以为一组有限的类型专门化模板,然后有一个私有实现。
    【解决方案4】:

    路过的人

    你也可以在main中#include实现文件

    主要:

    #include "arrayobjclass.h"
    #include "arrayclass.h"
    
    #include "arrayobjclass.cpp"
    #include "arrayclass.cpp"
    

    【讨论】:

      猜你喜欢
      • 2012-03-10
      • 2014-04-30
      • 2015-10-12
      • 2012-05-24
      • 2020-01-29
      • 2012-02-03
      相关资源
      最近更新 更多