项目开发过程中发现一个问题,有段代码,一个动态库的cpp代码里不包含头文件中类的空构造空析构实现,就会出现编译出的动态库依赖项少了很多。而添加后则多了好几个依赖项。下面看例子:
1 ##a.h 2 class A{ 3 public: 4 A(){} 5 ~A(){} 6 void f(); 7 private: 8 T1 t1; 9 T2 t2; 10 }; 11 12 ##a.cpp 13 #include "a.h" 14 void A::f(){t1=0,t2=0;} 15 16 ##b.cpp 17 #include "a.h" 18 int main(){ 19 A a; 20 return 0; 21 }
假设代码中的T1、T2都是来自T.so文件。我们的目的是由a.so依赖T.so,而最终的b.cpp生成的可执行文件仅仅依赖a.so即可。这样的需求,是项目开发中很常见,动态库依赖链,清晰简明。但是上面的代码却没有达到目的,因为a.so并没有依赖T.so,而b可执行文件,称之为b.out吧,b.out却需要显式依赖T.so才能编译通过。为什么?当我们尝试把A类的构造和析构写在a.cpp中时,就达到了b.out依赖a.so,a.so依赖T.so的目的。
估计你也发现原因了。t1,t2的实现和a.cpp无关。即使用到了t1,t2,但是作为动态库,运行是在被动态调用时候才运行的,编译期t1,t2来自头文件,不用考虑其实现,故而不需要依赖。而构造函数搬到了cpp中后,构造时候需要对t1,t2实现。
而在项目开发中,这样的情况很常见,代码要更复杂。养成在cpp中实现构造和析构的习惯是有必要的。