c++內存模型和名稱空間

一、頭文件

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章