C++为什么不能把函数实现放在头文件里?
以前一直觉得这样写不符合规范,因为头文件可能会expose给client,但是实现不应该expose给client;这是一个隐藏技术细节(或者机密)的问题。
最近偷懒,把实现放在头文件里,发现还有一个c++编译的原因。
Hi.h
#pragm once
Void Hi()
{Printf(“hello”);}
a.cpp
#include “Hi.h”
Void A() {Hi();}
b.cpp
#include “Hi.h”
Void B() {Hi();}
work.cpp
//…
Main()
{
A();
B();
}
这里Hi的实现放在了.h文件,compile的时候会出现 duplicate实现的error。
根源是什么呢?编译的时候,a.cpp,b.cpp和work.cpp分别被compile成不同的object文件,然后做link;在work.obj里面,发现引用的a.obj和b.obj各有一个Hi的实现,因为a和b里面都include了Hi。如果Hi的实现不在头文件里(假设在Hi.cpp),compile的时候, Hi的实现在Hi.obj里面, a.obj和b.obj就没有;在link的时候,work.obj才会去Hi.obj找Hi的实现。
当然,一定要把实现放在头文件也有路可循。
Hi变成inline;但是这个只对小函数适用。另外一个路子,就是把这些实现变成static。以上面的为例,static voidHi() {...}。之后,Hi在a.obj和b.obj中可见,但是在work.obj中不可见,不会有前面的link问题
这两个方法,其实我严重不推荐。为什么呢?deploy的问题。如果头文件中的实现改了,所有相关的lib和dll都受影响。相反,如果实现在一个cpp文件中,而这个cpp又是在一个dll中,那么实现的改动,只需要重新发布一个dll。
本文探讨了C++编程中为何通常不将函数实现置于头文件,主要考虑因素包括隐藏技术细节、避免编译错误及链接问题。当头文件包含实现时,可能导致重复定义错误。解决方案包括使用inline函数(适用于小型函数)或使用static修饰函数,但这些方法可能带来部署问题,因为头文件中的任何改动将影响所有依赖它的库和动态链接库。
1915

被折叠的 条评论
为什么被折叠?



