.h : 书写声明
.cpp: 书写定义
声明与定义
声明: extern 变量 extern int value; //声明
函数原型 fun();
类只有声明
struct只有声明
定义: int value; //定义
函数定义; fun() {}
.h只放声明:避免多个.cpp,include同一个.h时,链接出现重复定义的东西.
“#include .h的作用:是给出的.h整个文本,全部放到.cpp中去, 成为一个大的文本文件. 然后这个文本文件进行编译器编译.
/* a.h
*/
void f(); //声明
int global; //定义,不可以放在.h中
/* a.cpp
*/
#include "a.h"
int main()
{
return 0;
}
//程序书写错误,原因是.h中只可以放声明不可以放定义. 故int global;不能放在.h中.
//解释为什么不可以.h中放声明
/* a.h
*/
void f(); //声明
int global; //定义,不可以放在.h中
/* a.cpp
*/
#include "a.h"
int main()
{
return 0;
}
/* b.cpp
*/
#include "a.h"
void f()
{
}
g++ a.cpp b.cpp, 程序将出错. 原因是a.ii 有一个全局变量global
a.o 有一个int global;
b.ii 有一个全局变量global;
b.o 有一个int global;
这两个global是重名的.
编译可以通过: 因为编译器只是针对一个编译单元,一个源代码文件进行编译.
编译a.cpp时不知道b.cpp存在
链接不通过: 因为a.o会把b.o合在一起,此时将会发现有2个int global重名.
.ii: 编译预处理指令得到.ii
.s: 编译器得到.s
.o: 汇编器得到.o
.out: 链接器得到.out
/* a.h
*/
void f(); //声明
extern int global; //加extern表明是声明
/* a.cpp
*/
#include "a.h"
int main()
{
return 0;
}
/* b.cpp
*/
#include "a.h"
void f()
{
global++;
}
g++ a.cpp b.cpp 程序仍然出错, extern int global; 只是声明,但是没有定义.
extern int gloabl; 只是声明: 只知道这世界上有一个int global
未定义: 不知道在哪里
编译器可以通过,但是给global留了空间,让链接器找出来. 结果由于未定义,不知道在哪里,故链接失败.
/* a.h
*/
void f(); //声明
extern int global; //加extern表明是声明
/* a.cpp
*/
#include "a.h"
int main()
{
return 0;
}
/* b.cpp
*/
#include "a.h"
void f()
{
}
g++ a.cpp b.cpp 程序运行成功,原因是:虽然global只声明未定义,不知道在哪里,但是a.cpp未使用global, b.cpp也未使用global. 故链接成功.
写程序习惯:消灭所有的warning.
总结: 在.h中只能放声明,不能放定义.
原因:若在.h中放定义,则一个程序中需要多个cpp文件,include同一个头文件, 则会出现重名现象,链接失败.
“#include “.h” 当前路径
“#include <.h> 系统路径
“#ifndef #define ……… #endif”(标准头文件结构)
防止一个.cpp中include同一个.h多次,防止.h中类的声明多次出现.
/* a.h
*/
void f(); //声明
extern int global; //加extern表明是声明
class A
{
};
/* a.cpp
*/
#include "a.h"
#include "b.h"
int main()
{
A a;
return 0;
}
/* b.h
*/
#include "a.h"
extern A a;
程序出错,原因:
a.ii
{
//#include “a.h”
void f();
extern int global;
class A
{
};
//#include “b.h”
但是b.h中又包括a.h,故
void f(); //可重复出现
extern int global; //可重复出现
class A //不可重复出现
{
};
extern A a;
……加a.cpp
}
解决办法
/* a.h
*/
#ifndef _A_H_
#define _A_H_
void f(); //声明
extern int global; //加extern表明是声明
class A
{
};
#endif
/* a.cpp
*/
#include "a.h"
#include "b.h"
// 预编译环节include "b.h"时,已经第2次#include "a.h" 此时#ifndef _A_H_ 将起作用.
int main()
{
A a;
return 0;
}
/* b.h
*/
#include "a.h"
extern A a;