国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

[BoolanC++微專業] Week2筆記

2019-11-11 07:36:59
字體:
來源:轉載
供稿:網友

一、類的分類:

類在包含內容上大致可以分為以下兩種形式:

class with pointer members ——string類 在構造這種類的時候,拷貝構造函數,賦值與比較運算符重載,全部都要特殊考慮,很可能出現違背開發者意圖的行為。

class without point members ——complex類

二、三大特殊函數:

String類的實現

三大特殊函數即為:

拷貝構造函數: String(const String &str);

賦值運算符重載:

String& Operator=(const String&str);

析構函數:

~String();

在class with pointer members里必須存在拷貝構造函數三大函數。如果使用編譯器合成的默認函數的話會出現俗稱的“淺拷貝”和“內存泄漏”。 舉例說明:

String a("Hello"); String b(a);

若使用的是一個默認的拷貝構造函數,則會使兩個類中的m_data指針指向同一個”Hello”,那么假設析構函數正常運行,a的lifetime終止的時候,會釋放a->m_data指向的”Hello”內存塊。但是b的lifetime并沒有終止,那么b->m_data會指向一個已經被釋放的內存塊,形成空懸指針,萬一在程序的某處使用b,則會出現內存錯誤。賦值函數同理。 我們都知道一個指針有new必有delete,類在lifetime結束的時候,會將所有的在棧上占用的內存還給計算機,但是class with pointer里指針指向的內存全部來自堆上,如果不主動釋放,那么此內存塊將會一直被占用,在小程序中可以并不會出現什么大的問題,但是如果一個類有足夠多個實例,那么將會將堆中的內存全部占用,造成堆中無內存可用的狀況,就是俗稱的“內存泄漏”。

拷貝構造函數讓我們發現一個很有意思的特性:

inline Stirng::String(const String &str) { m_data = new char[strlen(str.m_data)+1]; strcpy(m_data,str.m_data) } 有同學

可能發現了 str和我本身這個類的實例,并不是友元,我為什么可以訪問它的PRivate成員? 因為從同一個類中衍生出的實例互為friend。

在拷貝賦值函數中,有一點非常重要,即是要檢測rhs是否是類本身,如果是,可以節省拷貝的時間和空間。如果不是,不檢查的話,可能產生不確定行為,如圖所示:

三、所謂棧和堆: Stack,是存在某作用域的一塊內存空間,隨著你所使用的函數的調用和結束產生以及返回,在函數本體內聲明的任何變量,所使用的內存塊都取自棧(stack)。 這里寫圖片描述 heap,是指操作系統提供的一塊global內存空間,程序可以動態分配從中獲取若干區塊。這里寫圖片描述 具體區別可以參照StackOverFlow 問題:What and where are the stack and heap? 棧中的變量,lifetime與包含它的函數同時存在,在函數聲明周期結束時,它的生命周期同時存在。 stack object和global object的lifetime在作用域結束后依然存在,直到整個程序結束時才會結束。 heap object卻不同,在new開始后,如果作用域結束,指針的lifetime結束,但是其指向的內存卻一直沒有被釋放,一直到程序結束,但是我們已經沒有能力再次通過指向它的指針對其進行delete等其他操作,這就造成了內存泄漏。

分配在heap上的數據,有new必有delete。 接下來看一下new和delete的實現。

void *operator new(size_t); //allocate an objectvoid *operator delete(void *); //free an objectvoid *operator new[](size_t); //allocate an arrayvoid *operator delete[](void *); //free an array

 c++中new和delete函數是不允許重載的,屬于特殊函數,雖然函數聲明有點不太一樣,但是同學們- - 這個真的是函數。new和delete通常需要成對出現,因為其底層實現的原理有所不同,在此不進行討論,其底層最終都是調用c語言的malloc free來進行內存的分配與釋放,但是在delete時 如果delete一個類的時候,會先調用類的析構函數然后再釋放內存,而free并不會(這不廢話么- - 有free的時候c++還不直到在哪里呢)。new先分配memory,再調用構造函數。   四、動態內存分配所得的array: 這里寫圖片描述

這是侯捷老師在debug模式下截取的一個動態分配所得的array內存塊。一個complex內有2個double數據。其中關于debugger header的部分本人水平所限,理解有限。。。就扔一張圖,不獻丑了。

五、關于static的補充:     類的靜態成員存在于任何對象之外,對象不包含任何與靜態成員有關的數據,類似的,靜態成員函數,也不與任何對象綁定在一起,他們不包含this指針,作為結果,靜態成員函數不能聲明成const的,而且我們也不可以在static函數內使用this指針。我們可以使用作用域運算符直接訪問靜態成員:  

   double r;    r = complex::static_function();

成員函數不通過作用域運算符可以直接訪問靜態成員。     定義靜態成員:     我們可以在類的內部或者外部定義靜態成員函數,在類的外部定義靜態成員時,不能重復static關鍵字。     因為靜態數據成員不屬于類的任何一個對象,所以他們不是創建類的對象時被定義的。這意味著他們不是由類的構造函數初始化的。而且一般來說,我們不能在類的內部初始化靜態成員。相反的,必須在類的外部定義和初始化每個靜態成員。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 修文县| 通城县| 辉南县| 宁陕县| 雷波县| 达拉特旗| 青阳县| 松滋市| 固原市| 潜江市| 惠安县| 崇州市| 陇西县| 东乡族自治县| 德江县| 叶城县| 和田县| 垦利县| 锦州市| 湘潭县| 赤壁市| 巴彦县| 房山区| 广昌县| 景谷| 永丰县| 砚山县| 黎城县| 临沂市| 禄丰县| 镇安县| 康马县| 垣曲县| 平度市| 满洲里市| 高雄市| 巴林左旗| 项城市| 西畴县| 蓝田县| 吐鲁番市|