基础:
一个.cpp对应一个obj,一个.obj就是一个编译单元,多个编译单元在链接的时候通过链接器链接,组成一个exe,就是一个程序。如果一个cpp需要另外一个cpp定义的函数,只需要在这个cpp中写上这个函数的声明就可以了,注意在链接的过程中如果有同名的函数或者变量在不同的obj中,程序运行会报错。(实际上在编译的时候,就会提示出现重定义的错误。)在实际的调试过程中发现,变量的重定义在编译的过程中能够立即检测出来,而函数的重定义则不同,如果你首先在一个cpp里面实现该函数的定义,然后运行成功,然后在另外一个cpp函数里面再实现相同的函数的定义,那么程序将不会报错,rebuild all以后,报错,个人认为是编译器优化的原因。
避免这种问题的方法:extern 和 static; extern是外部链接的意思,也就是除了这个单元,外部的单元
也是能够访问这个函数的.static 是内部链接,自属于自己单元.
心得:对于全局变量尽量不要在.h文件中定义,如果有两个.cpp及以上包含该.h文件,就会出现变量重定义。
如果要使用全局函数,可以在一个cpp文件中定义该变量,在其他需要的.cpp文件中extern该函数即可 (不需要包含任何头文件)(.h文件在编译的时候会在cpp文件中扩建开)。
对于static关键字,只能在当前编译单元看到,对外部不可见。
记住: 在c++中,变量声明只有在受用extern关键字的时候才成立,其他情况都是定义,而在使用extern的同时给变量赋初值,那么声明变为定义,同时extern被编译器忽略(经过自己验证)。c++变量缺省情况下是全局的,对所有源文件是可见的,如果加上static关键字,会被认为是局部的变量,对外部不可见。
1 不要把定义放在.h中,容易导致重复定义
2 尽量把变量定义为static,限制在局部范围内,除非使用全局的。
对于const和typedef是例外,const和typedef默认是局部的,不需要使用static,因此可以在.h文件中使用const变量不会产生重定义,编译器会为每一个引用该.h的源文件申请一份该变量的局部定义,就像该变量定义在该原文件中,但此时和其他使用该变量的源文件是独立的,彼此没有联系。
3 对于static关键字,如果修饰函数内定义的变量或者类内部定义的成员变量时,称为静态变量,修饰其他变量时,称为局部变量。
而对于函数,默认情况为extern, 一般函数都为“外部”函数,
所以在声明函数时不用加"extern".
如果在一个文件中声明函数时加了"static", 表示这个函数只在这个文件内可见。
<>h文件作用
1 方便开发:包含一些文件需要的共同的常量,结构,类型定义,函数,变量申明,
2 提供接口:对一个软件包来说可以提供一个给外界的接口(例如: stdio.h)
<>h文件里应该有什么
常量,结构,类型定义,函数,变量申明
<>h文件不应该有什么
变量定义, 函数定义
<>extern问题
对于变量需要extern,
对于函数不需要因为函数的缺省状态是extern的.如果一个函数要改变为只在文件内可见,加static
<>include包含问题
虽然申明和类型定义可以重复,不过推荐使用条件编译#ifndef _FILENAME_H, #define _FILENAME_H, #endif
<>应该在那儿包含h文件
在需要的地方.比如某个提供接口的h文件仅仅被1.c文件需要,那么就在1.c文件里包含
条件编译目的是防止头文件的重复包含和编译,可能会导致编译速度降低,但不是错误!?