C++ 链接器错误 - 未定义引用"到未内联定义的函数

c++ linker error - 'undefined reference' to not inline defined functions

本文关键字:定义 函数 链接 错误 引用 未定义 C++      更新时间:2023-10-16

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

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,还是在代码::块中使用build函数,都没有区别。

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

看起来您正试图单独编译一个模板。这在一般情况下是不可能的,因为模板只有在使用时才会被实例化,而且它永远不会在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>;