几天后,我正在尝试使用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文件时,编译器没有返回任何错误,因此我认为这只是链接器问题。
答案 0 :(得分:4)
看起来您正在尝试单独编译模板。这通常是不可能的,因为模板仅在使用时才会被实例化,并且永远不会在DList.cpp
文件中使用。尝试以下两种方法之一:
DList
中函数的定义移动到头文件中(这是正常的处理方式)。DList
的一些显式实例化放入DList.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>;