0

几天来,我正在尝试使用 Code::Blocks IDE(在 Linux,Ubuntu 64 位上)编译一个用 C++ 编写的项目。代码有效,但存在一些链接器错误。我注意到对于未在类中内联定义并且在其他文件中的函数(类是 i *.h 文件,这些函数的定义在 *.cpp 中),我收到错误“未定义的引用”。我尝试编写自己的 Makefile,但没有帮助。

生成文件:

all: project

project: main.o DList.o Person.o
    g++ main.o DList.o Person.o -o project

main.o: main.cpp
    g++ -c main.cpp

DList.o: include/DList.cpp
    g++ -c include/DList.cpp

Person.o: include/Person.cpp
    g++ -c include/Person.cpp

clean:
    rm -rf *.o

尽管我在网上阅读了一些有关这些错误的信息,但我不知道该怎么办。

// 编辑我将 Object.cpp 和 Object.h 更改为 Person.cpp 和 Person.h,将 *.cpp 文件移动到主目录并更改了 *.cpp 文件中的#include 路径。

错误:

obj/Debug/main.o||In function `main':|
...main.cpp|19|undefined reference to `DListIterator<Person>::go(int)'|
...main.cpp|20|undefined reference to `std::basic_ostream<char, std::char_traits<char> >& operator<< <Person>(std::basic_ostream<char, std::char_traits<char> >&, DList<Person>&)'|
...main.cpp|21|undefined reference to `DList<Person>::~DList()'|
...main.cpp|21|undefined reference to `DList<Person>::~DList()'|
obj/Debug/main.o||In function `DList<Person>::insert(Person&)':|
...include/DList.h|45|undefined reference to `DList<Person>::insert(Person&, DListIterator<Person>&)'|
||=== Build finished: 5 errors, 0 warnings ===|

如果我在命令行中构建开始 make 或在 Code::Blocks 中使用 Build 函数,这没有区别。

当我将所有代码从 *.cpp 文件复制到 *.h 文件时,编译器没有返回任何错误,所以我认为这只是链接器的问题。

4

1 回答 1

4

看起来您正在尝试单独编译模板。这通常是不可能的,因为模板只会在使用时被实例化,而不会在DList.cpp文件中使用。尝试以下两种方法之一:

  • 将函数的定义移动DList到头文件中(这是正常的处理方式)。
  • 将 in 的一些显式实例化DListDList.cpp文件中。(例如template class DList<Person>;:)

问题的完整示例:目前您有:

//DList.h
template<typename T>
class DList {
    void insert(T& newPerson);
    //etc
};

//DList.cpp
#include "DList.h"
//The when this is being compiled, 
//the compiler does not know about Person,
//so it cannot instantiate this function.
template<typename T>
void DList<T>::insert(T& newPerson) {
    //implementation
}
//etc

//main.cpp
#include "DList.h"
#include "Person.h"
int main() {
    //When this is being compiled, it does not know the
    //definition of the out-of-line functions in `DList`,
    //so it cannot instantiate them.
    DList<Person> people;
    people.insert(Person("Joe"));
}

一种可能的解决方法是删除DList.cpp定义并将其放入“DList.hpp”中:

//DList.hpp
template<typename T>
class DList {
    void insert(T& newPerson) {
        //implementation
    }
    ~DList();
    //etc
};
//the implementations can alternatively be
//placed outside the class, but in the header:
template<typename T>
DList<T>::~DList() {
    //implementation
}

另一个修复是显式实例化DList(在定义可用的编译单元中):

//DList.cpp
#include "DList.h"
#include "Person.h"
template<typename T>
void DList<T>::insert(T& newPerson) {
    //implementation
}
//Explicit instantiation:
template class DList<Person>;
于 2012-08-28T07:50:16.297 回答