一、頭文件
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