每日學習筆記 名字空間,new和delete

2021-06-02 08:00:01 字數 3612 閱讀 2260

在c++中盡量用而不用

名字空間是管理標示符的一種方法,就是說在同乙個名字空間下面只能訪問這個名字空間內的標示符

簡單的例子就是說比如說  

使用了#include   這個巨集使用了以後所有 iostream.h 裡面的定義的函巨集 等等   表示都是在全域性名字空間下面

(全域性名字空間就是平時你使用的那個)

你寫cout   cin等等常用的東西, 編譯系統就能夠找到相應的函式定義 而如果你使用了#include   相當於把所有iostream.h裡面的標示符的定義都放在了std名字空間裡面了,這個時候你使用cin , cout   編譯器就找不到他們的定義了,必須使用   std::cin   或者   std::cout (或者在開頭寫上   using   namespace   std;) 

關鍵字namespace定義了乙個名字空間,裡面的變數和函式,宣告在此名字空間外使用須在前面加名字空間名稱.例如:

#includenamespace my

class test

void fb()

提示報錯.因為沒有乙個例項,也就是物件來呼叫這個函式

(二)new和delete(部分摘自effective c++)

(1)new和delete的用法**自

new用法:

1.     開闢單變數位址空間

1)new int;  //開闢乙個存放陣列的儲存空間,返回乙個指向該儲存空間的位址.int *a = new int 即為將乙個int型別的位址賦值給整型指標a. 

2)int *a = new int(5) 作用同上,但是同時將整數賦值為5

2.     開闢陣列空間

一維: int *a = new int[100];開闢乙個大小為100的整型陣列空間

二維: int **a = new int[5][6]

三維及其以上:依此類推.

一般用法: new 型別 [初值]

delete用法:

1. int *a = new int;

delete a;   //釋放單個int的空間

(2)在c++中盡量使用new和delete而不使用malloc和free

因為new和delete支援建構函式和析構函式而malloc和free不支援。另外new和delete必須成對使用,malloc和free必須成對使用!(當在c++中使用了智慧型指標:auto_ptr時除外)

(3) 下面的語句有什麼錯?

new的使用包含了兩個步驟,首先記憶體被分配,然後被分配的記憶體呼叫乙個或者多個建構函式。相應的delete也包含了兩個步驟,首先為將被釋放的記憶體呼叫乙個或者多個析構函式,然後釋放記憶體。

string *stringarray = new string[100];

...delete stringarray;

雖然是乙個new對應乙個delete,但是stringarray 指向的 100 個string 物件中的99 個不會被正確地摧毀,因為他們的析構函式永遠不會被呼叫。

此問題可以考慮為當我們用delete的時候是呼叫乙個物件還是乙個物件陣列,顯然上面的**只是釋放了乙個物件,而不是乙個物件陣列,正確的**如下:

string *stringarray = new string[100];

...delete stringarray;

4)析構函式裡對指標呼叫delete

在每個建構函式裡對指標進行初始化。對於一些建構函式,如果沒有記憶體要分配給指標的話,指標要被初始化為0(即空指標)。  刪除現有的記憶體,通過賦值操作符分配給指標新的記憶體。   在析構函式裡刪除指標。

(5)事先準備好記憶體不夠的情況

那麼,怎麼辦?如果想用乙個很簡單的出錯處理方法,可以這麼做:當記憶體分配請求不能滿足時,呼叫你預先指定的乙個出錯處理函式。這個方法基於乙個常規,即operator new不能滿足請求時,會在丟擲異常之前呼叫客戶指定的乙個出錯處理函式——一般稱為new-handler函式。

指定出錯處理函式時要用到 set_new_handler 函式,它在標頭檔案裡大致是象下面這樣定義的:

typedef

void

(*new_handler

)();

new_handler

set_new_handler(

new_handler

p)throw

();

可以看到,new_handler 是乙個自定義的函式指標型別,它指向乙個沒有輸入引數也沒有返回值的函式。set_new_handler 則是乙個輸入並返回new_handler型別的函式。 例:

void

nomorememory()

int

main()

假如operator new不能為100,000,000 個整數分配空間,nomorememory將會被呼叫,程式發出一條出錯資訊後終止。這就比簡單地讓系統核心產生錯誤資訊來結束程式要好。

(6)寫operator new和operator delete 時要遵循常規

當你要實現自己的記憶體管理方案或其它一些必要情況,那麼就用

運算子過載

來對new 和delete過載,記住它們在c++中不是函式,而是操作符.

自己重寫operate new時候必須要保證一下幾點

1)有正確的返回值

2)可用記憶體不夠要呼叫出錯處理函式

3)處理好0位元組請求的情況

考慮到以上幾點,有關返回值的部分,如果記憶體分配成功,則返回指向已經被分配的記憶體的指標,如果記憶體分配失敗,則應該呼叫出錯處理函式,並指望該出錯處理函式能夠想辦法去釋放其它地方記憶體而使得operate new 最終能夠分配到想要的記憶體,只有在出錯處理函式為空的情況下operate new 才會丟擲乙個異常。另外c++標準要求,在請求分配0位元組記憶體時候,operate new也要返回乙個合法的指標(可以把它當作一位元組的請求來處理)

非類成員形式的operator new的偽**看起來會象下面這樣:

void *operate new (size_t size)

while(1)  //分配size位元組的記憶體 }

當在基類中寫operate new 時,同時其還可能被子類繼承,應該像下面這樣寫

void * base::operator new(size_t size)

class derived: public base    

對於operate delete,情況要簡單一些,記住c++保證刪除空指標永遠是安全的,

void operator delete(void *rawmemory)

(7)使用operate的注意事項

1)避免隱藏標準形式的new  (內部範圍的宣告名稱會隱藏掉外部範圍的宣告名稱)

2) 如果寫了operator new就要同時寫 operator delete

乙個 (忘記名字)的逆向題

這個看起來好像是很難的 但其實很簡單 也就那些東西 細細分析 也沒有什麼 然後觀察陣列 就可以 了 include include include include include includeusing namespace std char s l3t me t3ll y0u s0m3th1ng ...

每日學習筆記 3

1,先說說今天體會最深刻的一點 寫 python 乙個好的編輯器至關重要,這其中 vim確實是最佳選擇。由於 python 是根據縮進來判斷上下文的,因此 tab和空格使用不當會害死你的。一段 在 notepad 裡看起來對齊格式沒問題,可就是死活編譯不過,來到 vim下一看,damn it,格式是...

每日學習筆記 15

今天接著讀 mysql技術內幕innodb儲存引擎 的第5章關於索引這部分內容。什麼時候使用b 樹索引?並不是在所有的查詢條件下出現的列都需要新增索引,作者指出當訪問表中很少一部分行時,使用b 樹索引才有意義。對於像性別,地區,型別等字段,它們的可取值範圍很小,即所謂低選擇性,比如select fr...