C++ 的项目一旦过大,对文件的复用,整理等操作有了严格的要求.前一段时间就为自定义头文件的引入头疼了好久,现在说说我填过的坑.
一.头文件,源文件的概念,关系这里不赘述了,网上的博客太多了,并且都比较详细.
这里给个文章地址:http://www.cplusplus.com/forum/articles/10627/
二.遇到的问题
1.文件引用无误但....
yuan@localhost:~/Desktop/temp$ g++ main.cpp -o a
/tmp/ccTqCUgO.o:在函数‘main’中:collect2: error: ld returned 1 exit status
神马? 没定义?
定义了啊!为什么不能...
三.建议
写项目一定要严谨,不要混淆各个文件
.h(还有.hpp等)文件是头文件,只写变量,函数,模板,类的声明.
.c(.cpp,.cc等)文件写头文件中声明的文件的定义,每一个模块写一个文件不要相互混淆
对于头文件中有模板类的情况,建议讲类的函数定义写在头文件中,因为有时会报错
四.填坑
现在说说我遇到的问题的解决,
首先创建头文件
//a.h
#ifndef _A_H_ //这个是头文件的宏,只要满足变量的命名规则就行
#define _A_H_
//函数的声明
void show();
#endif
//a.cpp
#include "a.h"
#include
void show(){
std::cout << "引用成功"<
}
//main.cpp
#include "a.h"
int main(){
show();
return 0;
}
整个文件的编写,引入都没有问题,那为什么会报错呢?让我来告诉你,
1.a.h文件写的是函数的声明
2.a.cpp文件写的函数的定义,此处在文件中引入了a.h,#include"XX"的意思就是把文件的内容替换#include
3.直接在main文件中引入了a.h,如果按照#include只是把文件的内容替换掉的话,好像main.cpp中只有show函数的声明,和show函数的调用.这不就又错了嘛!实则不然,在c++的编译器编译时,压根不管各个文件的相互关系,只在乎当前文件有没有我要的信息,在mian.cpp中文件的声明有,则编译可以通过.在C++编译时,有两个同名文件(后缀不同),a.h与a.cpp,其实名字可以不同,一般建议名字一致.在编译时,编译器会自动查找整个工程文件中有没有对头文件中的函数的定义,有则引用,没有就报错,不会在乎文件的位置和名字,前提要在同一工程目录下,且文件的引入路径正确.也就是说.在编译时,main函数调用的函数在头文件中声明就行,而文件的定义只要在同一工程下的文件中有定义即可,并且不用引入到调用处.切记:在头文件中写函数的定义也可以成功编译,引入定义函数的cpp文件后也可以编译,(因为两个文件与.txt文件没有区别)但是不要将CPP文件引入,可能会造成函数的多次定义而报错,况且头文件也有重复引入的危险(所以用#ifndef #define ...#endif取消重复引入).
4.之后所以报错的原因是没有全部编译,整个项目包含多个头文件和源文件,编译器在编译时是分别编译各个cPP文件的,不会编译头文件,因为也没有用.在执行时从main函数开始.而我报错的原因就是只编译的main.cpp而没有编译所有相关的cPP文件,所以报错.(注:文件的编译是分别编译,然后链接,而程序运行是从mian 函数开始,所以不要只编译含mian 函数的文件)
5.所以编译整个工文件就可以使文件正常运行
注:模板的声明与实现不能分开写,必须写在同一文件中(但是我在测试时可以分别写,但是不建议)
https://www.zhihu.com/question/20630104