1. 程式人生 > >C++ 學習筆記三

C++ 學習筆記三

1.檔案和流

2.C++動態記憶體分配

  • 棧:在函式內部宣告的所有變數都將佔用棧記憶體。
  • 堆:這是程式中未使用的記憶體,在程式執行時可用於動態分配記憶體。

    在 C++ 中,您可以使用特殊的運算子為給定型別的變數在執行時分配堆內的記憶體,這會返回所分配的空間地址。這種運算子即 new 運算子。如果您不再需要動態分配的記憶體空間,可以使用 delete 運算子,刪除之前由 new 運算子分配的記憶體、

 malloc() 函式在 C 語言中就出現了,在 C++ 中仍然存在,但建議儘量不要使用 malloc() 函式。new 與 malloc() 函式相比,其主要的優點是,new 不只是分配了記憶體,它還建立了物件。在任何時候,當您覺得某個已經動態分配記憶體的變數不再需要使用時,您可以使用 delete 操作符釋放它所佔用的記憶體。

double* pvalue = NULL; // 初始化為 null 的指標

pvalue = new double; // 為變數請求記憶體

delete pvalue; // 釋放記憶體

char* pvalue  = NULL;   // 初始化為 null 的指標
pvalue  = new char[20]; // 為變數請求記憶體
delete [] pvalue;        // 刪除 pvalue 所指向的陣列

 

物件的動態記憶體分配

Box* myBoxArray = new Box[4];

delete [] myBoxArray; // 刪除陣列

delete 與 delete[] 區別:

針對簡單型別 使用 new 分配後的不管是陣列還是非陣列形式記憶體空間用兩種方式均可 如:

int *a = new int[10];   
delete a;   
delete [] a; 

針對類Class,兩種方式體現出具體差異

// 僅釋放了a指標指向的全部記憶體空間 但是隻呼叫了a[0]物件的解構函式 剩下的從a[1]到a[9]這9個使用者自行分配的m_cBuffer對應記憶體空間將不能釋放 從而造成記憶體洩漏
delete a;
// 呼叫使用類物件的解構函式釋放使用者自己分配記憶體空間並且   釋放了a指標指向的全部記憶體空間
delete [] a;

對於像 int/char/long/int*/struct 等等簡單資料型別,由於物件沒有 destructor,所以用 delete 和 delete [] 是一樣的!但是如果是C++ 物件陣列就不同了!

 

new 和 malloc 內部的實現方式有什麼區別?

new 的功能是在堆區新建一個物件,並返回該物件的指標。

所謂的【新建物件】的意思就是,將呼叫該類的建構函式,因為如果不構造的話,就不能稱之為一個物件。

而 malloc 只是機械的分配一塊記憶體,如果用 mallco 在堆區建立一個物件的話,是不會呼叫建構函式的。

嚴格說來用 malloc 不能算是新建了一個物件,只能說是分配了一塊與該類物件匹配的記憶體而已,然後強行把它解釋為【這是一個物件】,按這個邏輯來,也不存在建構函式什麼事。

同樣的,用 delete 去釋放一個堆區的物件,會呼叫該物件的解構函式。

用 free 去釋放一個堆區的物件,不會呼叫該物件的解構函式。

3.C++ 名稱空間

4.C++ 前處理器

前處理器是一些指令,指示編譯器在實際編譯之前所需完成的預處理。

所有的前處理器指令都是以井號(#)開頭,只有空格字元可以出現在預處理指令之前。預處理指令不是 C++ 語句,所以它們不會以分號(;)結尾。

#define 預處理指令用於建立符號常量。該符號常量通常稱為巨集,指令的一般形式是:  #define PI 3.14159

引數巨集:使用 #define 來定義一個帶有引數的巨集,如下所示:#define MIN(a,b) (a<b ? a : b)

條件編譯

有幾個指令可以用來有選擇地對部分程式原始碼進行編譯。這個過程被稱為條件編譯。

條件前處理器的結構與 if 選擇結構很像。請看下面這段前處理器的程式碼:

#ifdef NULL
   #define NULL 0
#endif
#ifdef DEBUG
   cerr <<"Variable x = " << x << endl;
#endif
#if 0
   不進行編譯的程式碼
#endif

 

4.C++訊號處理;

訊號是由作業系統傳給程序的中斷,會提早終止一個程式。在 UNIX、LINUX、Mac OS X 或 Windows 系統上,可以通過按 Ctrl+C 產生中斷。

有些訊號不能被程式捕獲,但是下表所列訊號可以在程式中捕獲,並可以基於訊號採取適當的動作。這些訊號是定義在 C++ 標頭檔案 <csignal> 中。

// 註冊訊號 SIGINT 和訊號處理程式

signal(SIGINT, signalHandler);

用函式 raise() 生成訊號,該函式帶有一個整數訊號編號作為引數,語法如下:
int raise (signal sig);在這裡,sig 是要傳送的訊號的編號,這些訊號包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP

6.C++多執行緒

多執行緒是多工處理的一種特殊形式,多工處理允許讓電腦同時執行兩個或兩個以上的程式。一般情況下,兩種型別的多工處理:基於程序和基於執行緒

  • 基於程序的多工處理是程式的併發執行。
  • 基於執行緒的多工處理是同一程式的片段的併發執行。

多執行緒程式包含可以同時執行的兩個或多個部分。這樣的程式中的每個部分稱為一個執行緒,每個執行緒定義了一個單獨的執行路徑。