用C++ OOP写数据结构的时候,运行的时候就提示
Undefined symbols for architecture x86_64:
"AList<int>::AList(int)", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
部分代码如下(详细代码可以跳转到 GitHub仓库 进行查看)
main.cpp内容如下:
#include <iostream> #include "utils/ArrayList.h" int main() { auto *list = new AList<int>(10); list->append(1); cout << list->toString(); return 0; }
utils/ArrayList.h部分内容如下:
#include "List.h" #include <iostream> using namespace std; const int DefaultSize = 10; template<typename E> class AList : public List<E> { public: explicit AList(int size); };
utils/ArrayList.cpp部分内容如下:
#include "ArrayList.h" template<typename E> AList<E>::AList(int size) { // 实现 }
我也参照 StackOverflow 上的帖子进行了修改,但是所描述的内容就是:函数或方法声明需要添加在.h
文件中,而不是.cpp
文件中。
请问这个应该怎么解决?谢谢各位!
测试了一下,将实现代码放到 .h
文件中或者加上一句 #include "ArrayList.cpp"
就没问题了
简短的回答:用这个命令编译就行了
gcc main.cpp ArrayList.cpp -o program
原因对程序编译过程有个基本了解就懂了。
从源码到二进制需要经过一系列步骤(别杠我):
你的代码里,main.cpp 引用了 ArrayList 相关函数,只
#include
了声明,这个情况下编译器认为这些函数在其他地方定义,不需要知道定义编译器也可以完成1-4步。但是在第5步,你想要编译出一个可执行文件,编译器(准确说是链接器负责干这件事)必须找到 ArrayList 相关函数到底定义在哪儿,不然工作就没法干了。这一步必须告诉链接器所有要引用的符号应该在哪儿去找,也就是
gcc -lxxx
后面-lxxx
这个参数干的事,告诉链接器去xxx
这个库里找我引用的外部符号。你的案例中,ArrayList 的相关函数定义显然不能在编译器默认链接的库里找到,毕竟这是你自己的东西。所以就必须告诉编译器,请把 main.cpp 和 ArrayList.cpp 一起处理,链接的时候记得到 ArrayList.cpp 里找我引用的函数。
于是编译命令就成了上面的样子。当然也可以用另一种形式:
这样就是分别编译好 main.o 和 ArrayList.o 两个目标文件,然后告诉 gcc 麻烦把这两个目标文件给链接成
program
可执行文件。顺便一提
gcc
命令其实是一个驱动,真正编译和链接分别是cc1plus
和ld
干的。