情景
创建两个静态库 libA 和 libB,libB依赖libA。创建一个程序App引用 libB
关系为:App -> libB -> libA
一般做法是:
创建完libA后编译生成静态库,创建libB时引用该静态库并将libA的头文件复制到libB项目中进行引用。
App对libB的引用也是导入它的静态库和头文件。
可不可以不用头文件?
可以,头文件只其申明作用,你完全可以自己写该声明。事实上,#include 只是在编译时起作用,它仅仅将include的文件全量复制到源文件中。故和你自己写是一样的。
头文件和源文件名称能否不同
可以,还是上面说的,include仅仅将内容原封不动复制进源文件,所以和头文件命名没有什么关系。
如何在App中使用libA中定义的类和方法
如果是java程序,那么你完全可以直接在App项目中声明和使用libA中的类和方法,我认为这也是符合直觉的。
但在c++中,貌似有一条不成文的规定就是任何东西都需要先声明再使用,所以,若想在App中调用libA中的方法,要么你include libA的头文件,要么你手动声明需要调用的方法,然后就可以直接调用,至于调用的方法体,c++程序会在链接步骤自动找到。
举例:
App.cpp(一个Qt的示例程序)

pch.h

libA.h

extern 关键字
我在libB中定义了一个变量,我想在App中使用它,如果你这个变量定义在libB的头文件中这样做是没问题的,但如果你将其定义在了cpp文件中,那你在App中仅引入libB的头文件还是访问不到该变量。
此时,你就可以在头文件中使用extern关键字再次声明定义在cpp中的变量,然后在App中就可以使用了。
例如:
# libB.h
...
class MyClass{...}
extern int num;
extern MyClass mc;
...
# libB.cpp
...
int num = 1;
MyClass mc = MyClass();
...
# App.cpp
#include "libB.h"
...
int main()
{
std::cout << num << ", " << mc.somproperties;
}
...
但是我测试了下,貌似不能作用与class
extern class MyClass; // 这样貌似不行,我想如果可以这样的话是不是就能实现java中的那种链式引用的效果了(App中直接调用libA中定义的类而不用引入libA的头文件)
声明和定义
int num = 1; // 定义
extern int num; // 声明
定义就是在堆中开辟了一块内存并在栈中创建了其引用
声明只是在栈中创建了对定义在堆中数据的引用
注:该理解只是我的个人理解,类比JVM的一种猜测
总结
项目中引用的lib只是一个方法的集合,若需要使用这些方法需要先声明一下。
就好比一个餐馆,lib就相当于是厨师会做的菜,方法声明就相当于菜单,有时,菜单并不会将厨师会的所有菜品都列上,仅仅列出需要卖的就行。
但是,作为一个顾客,如果没有菜单只有厨师,我又不知道餐馆能做什么菜。如果只有菜单没有厨子(只有声明没有真实引入lib),就算我点了某个菜也是做不出来的。