本文转载自微信公众号《程序喵大师》,作者程序喵大师。转载本文请联系程序大师喵公众号。前两天突然看到部门一个项目的代码里全是#include"xxx.cpp"。我说没见过这种写法,引发了我的思考:问题一:这是什么东西?C++是一门高深莫测的语言,可以用任何方式编写,而#include本质上就是复制粘贴代码。不敢说别人写错了。可能开发者是C++老大,写了一些常人看不懂的东西。代码也正常。问题2:整个工程都这样引用,会不会导致某个功能被重复定义?为此,查了一些资料,做了一些测试:代码段1://file1.cc#includeusingstd::cout;voidddd(){cout<<"ddd\n";}代码段2://file2.cc#include"file1.cc"intmain(){ddd();return0;}代码段3://filec.cc#include"file1.cc"voidf(){ddd();}然后三个源文件一起编译链接:发现报错了,确实是多定义错误,一个函数不能有多定义也是事实。我又改了代码://file1.cc#includeusingstd::cout;inlinevoidddd(){cout<<"ddd\n";}把ddd函数改成内联函数,然后三个source文件编译链接在一起:编译成功,输出正常。我把普通函数改成成员函数再测试:代码段1:file1.cc#includeusingstd::cout;structA{inta_;voidfunc();};voidA::func(){cout<<"file1.cca"<usingstd::cout;structA{inta_;voidfunc(){cout<<"file1.cca"<templatestructB{Ta;voidff(){std::cout<<"temp\n";}};代码段2://filec.cc#include"temp.h"voidf(){Ba;a.ff();}代码段3://file2.cc#include"temp.h"intmain(){Ba;a.ff();return0;}all源文件编译链接:发现编译成功,运行正常,那么函数的定义不在类中怎么办?//temp.h#includetemplatestructB{Ta;voidff();};templatevoidB::ff(){std::cout<<"temph\n";}程序编译链接后:编译链接成功,输出正常。因此得出结论是编译器对模板做了特殊处理,无论模板类中的函数是否内联,都可以正常链接。这个结论其实不是我得出的(所以可信),而是gnu文档写的(参考文献最后一个链接)。上面的代码只是为了确认结论。大致意思如下:编译器对模板做特殊处理。如果函数不是内联函数,有两种处理方式:链接时随机选择一个定义,其他的丢弃。编译器会单独提出函数的定义。它是在单个文件中提到的,而这个文件是单独编译的,所以不会出现重复定义的问题。大功告成,如果您对此有任何疑问,请留言!参考https://zybuluo.com/uuprince/note/81709https://stackoverflow.com/questions/15866258/template-class-multiple-definitionhttps://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html