一、头文件
1. c++程序一般分为3部分:
头文件、实现头文件的源文件、调用函数的源文件
2. 头文件常包含的内容
(1)函数原型
(2)使用#define或者const定义的符号常量
被声明为const的数据具有特殊的链接属性(外部/内部/无),具备的链接性为内部,其作用域为包含头文件的当前源文件(类似static,但const修饰的为常量,不可改变其值),不会出现多次定义的情况,所以可行
(3)结构声明
(4)类声明
(5)模板声明
(6)内联函数
注意:
(1)使用#include
来包含文件,本质是将包含的文件与源代码合并,对于int global = 100
的外部变量只能被一个文件包含,所以不能放在头文件(否则破坏单定义规则);
(2)不要使用#include
来包含源代码文件,这样将导致多重声明
(3)同一个文件只能将同一个头文件包含一次,建议使用
#ifndef TEST_H_
#define TEST_H_
.... // include的内容
#endif
二、存储持续性、作用域和链接性
1. 存储持续性
(1)自动存储持续性
函数内定义,存在于函数内或者代码块
(2)静态存储持续性
函数外定义,static修饰,存在于程序运行周期
(3)线程存储持续性
thread_local修饰,存在于线程生命周期
(4)动态存储持续性
new分配,delete释放,自由存储或堆
2. 作用域和链接
链接性描述了名称如何在不同单元(文件)间共享,分为:
(1)外部
文件间共享
int global = 100; // test1.cpp 函数外定义
在test2.cpp使用需(符合单定义规则)
extern int global ;
(2)内部
只能由一个文件中的函数共享
const int a = 100; // 函数外定义常量(不能修改值)
static int b = 100; // 函数外定义静态变量
(3)无
不能共享,只能在函数或代码块中访问
补充:(函数和链接性)
函数的链接性默认为外部的(即可在文件间共享),储存持续性为静态的(存在于程序运行周期),所以不能同时在两个文件中定义一个相同的函数(违反单定义)。在另外一个cpp文件中使用某个cpp文件定义的函数时,可以通过#include引入头文件或者直接在函数上面写上要使用函数的声明。
// main.cpp 文件1
#include<iostream> // 这里只使用系统的头文件
int add(int a, int b); // 直接在函数上面写上要使用函数的声明(实际上是extern int add(int a, int b);对于函数而言,extern 关键字可以省略)
int main() {
using namespace std;
cout << add(1,2) << endl;
cin.get();
return 0;
}
// test.cpp 文件2
int add(int a, int b) {
return a + b;
}
二、名称空间
避免变量名称发生冲突(默认情况下,在名称空间中声明的变量链接性为外部的)
// test.h
#ifndef TEST_H_
#define TEST_H_
namespace Jack1 {
int a;
}
namespace Jack2 {
int a;
}
// main.cpp
#include<iostream>
#include"test.h"
int main() {
using namespace std;
using namespace Jack1;
cout << a << endl;
cin.get();
return 0;
}
// 等价main.cpp(因为Jack1名称空间在"test.h"头文件中引入了)
#include<iostream>
#include"test.h"
int main() {
using namespace std;
cout << Jack1::a << endl;
cin.get();
return 0;
}
#endif