亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

3小時OOP初探(C++)

2019-11-14 10:56:35
字體:
來源:轉載
供稿:網友

基于《Thinking in C++》

CPP復習筆記

1. 靜態成員變量

靜態成員變量用static修飾,它只屬于類而不是對象,因此所有這個類的對象享用同一個靜態變量值。

靜態成員變量必須要在類外初始化

type class::name = value;

初始化的時候不用帶static但需要有類型,PRotected,privated,public都可以被這樣初始化

靜態成員變量的調用

//通過類類訪問 static 成員變量Student::m_total = 10;//通過對象來訪問 static 成員變量Student stu("小明", 15, 92.5f);stu.m_total = 20;//通過對象指針來訪問 static 成員變量Student *pstu = new Student("李華", 16, 96);pstu -> m_total = 20;static 成員變量不占用對象的內存,而是在所有對象之外開辟內存,即使不創建對象也可以訪問。一個類中可以有一個或多個靜態成員變量,所有的對象都共享這些靜態成員變量,都可以引用它。static 成員變量和普通 static 變量一樣,都在內存分區中的全局數據區分配內存,到程序結束時才釋放。這就意味著,static 成員變量不隨對象的創建而分配內存,也不隨對象的銷毀而釋放內存。而普通成員變量在對象創建時分配內存,在對象銷毀時釋放內存。靜態成員變量初始化時可以賦初值,也可以不賦值。如果不賦值,那么會被默認初始化為 0。全局數據區的變量都有默認的初始值 0,而動態數據區(堆區、棧區)變量的默認值是不確定的,一般認為是垃圾值。靜態成員變量既可以通過對象名訪問,也可以通過類名訪問,但要遵循 private、protected 和 public 關鍵字的訪問權限限制。當通過對象名訪問時,對于不同的對象,訪問的是同一份內存。靜態成員變量可以成為派生類和基類共同使用的數值,也可以成為成員函數的可選參數。靜態成員變量可以是所屬類的類型,普通數據成員只能成為該類的指針或引用。

2. 靜態成員函數

靜態成員函數的地址可以用普通函數指針調用

class A{public: static fun(){}; int fun1(){};}int (*pf1)()=&base::fun;int (base::*pf2)()=&case::fun1;靜態成員函數不可以調用類的非靜態成員,因為這個靜態成員函數并不帶有this指針。靜態成員函數不可以同時聲明為 virtual const volatile函數。靜態成員函數不需要對象名即可調用。非靜態成員函數可以自由調用靜態成員函數和靜態成員變量。

3. 引用和地址

引用類似于某個變量的別名,完全享用同一片地址。引用必須在定義的時候初始化。引用對象已經初始化不能重新引用另外的變量。

4. 拷貝構造函數

CExample(const CExample& C)  就是我們自定義的拷貝構造函數。可見,拷貝構造函數是一種特殊的構造函數,函數的名稱必須和類名稱一致,它必須的一個參數是本類型的一個引用變量。

調用時機

類作為一個參數整體傳入一個函數的時候,需要調用這個類的拷貝構造函數,進行形參和實參的復制類作為一個結果返回的時候,先產生一個臨時變量,調用拷貝構造函數將返回值拷貝到臨時變量,析構返回的變量,再析構臨時變量

需要通過另一個變量初始化的時候

class mode{...}mode A(10);mode B = A;拷貝構造函數分為淺拷貝和深拷貝。

默認拷貝構造函數是淺拷貝的一種

默認拷貝構造函數無法處理靜態成員變量只是簡單復制需要自己寫淺拷貝構造函數進行靜態成員變量的復制如果被拷貝對象中包含指針,進行逐位拷貝后新舊兩個指針將指向同一個空間,并且將被重復釋放

深拷貝用于需要動態創建新空間時

Rect(const Rect& r) { width = r.width; height = r.height; p = new int; // 為新對象重新動態分配空間 *p = *(r.p); } 可以創建一個private的拷貝構造函數聲明來解決默認值拷貝。???

5. const

修飾指針變量時: 只有一個const,如果const位于*左側,表示指針所指數據是常量,不能通過解引用修改該數據;指針本身是變量,可以指向其他的內存單元。只有一個const,如果const位于*右側,表示指針本身是常量,不能指向其他內存地址;指針所指的數據可以通過解引用修改。兩個const,*左右各一個,表示指針和指針所指數據都不能修改。修飾函數參數時: 不能改變該參數的值。修飾函數時: 該函數不能改變調用的參數值,同樣地,該函數也不能調用任何非const函數。修飾返回值時: 指針返回時:只能賦值給同樣用const修飾的左值值傳遞時:const并沒有什么意義

6. 對象初始化和析構

空初始化:即無參數無括號形式

如int i,new int,new int[10].當在所有函數之外時,初始化為0;當在某一函數中時,沒初始化。

值初始化:即無參數有括號形式,且括號只能在類型名后,而不能在變量名之后,即只能創無名對象,對象被值初始化為0.

如:int() //創建了一個無名對象,其被值初始化為0.一般將該無名對象初始化化或賦值給某有名對象,或直接作為無名對象使用

顯式初始化:即有參數有括號形式,且當為有名對象時括號在對象名之后,為無名對象時括號在類類型名之后。

如:int i(5); new int(5);以下四種必須使用初始化列表: 初始化一個引用成員變量初始化一個const變量當我們在初始化一個子類對象的時候,而這個子類對象的父類有一個顯示的帶有參數的構造函數當調用一個類類型成員的構造函數,而它擁有一組參數的時候析構函數通常使用默認析構函數,但是在之前進行空間改變(指針移位等)的時候一定要自己寫析構函數。

析構數組或類組:

class A{ A(){m_a=new int[10];} ~A(){delete [] m_a;} int * m_a;}

強制類型轉換支持但并不推薦,推薦使用以下較溫和的方法:

pd = static_cast<double*>(pv);初始化列表不管怎么寫,初始化的順序也只是按照原類內聲明的順序進行。

7. 重載函數和默認參數

重載函數的調用匹配 精確匹配:參數匹配而不做轉換,或者只是做微不足道的轉換,如數組名到指針、函數名到指向函數的指針、T到const T;提升匹配:即整數提升(如bool 到 int、char到int、short 到int),float到double使用標準轉換匹配:如int 到double、double到int、double到long double、Derived*到Base*、T*到void*、int到unsigned int;使用用戶自定義匹配;使用省略號匹配:類似printf中省略號參數同一作用域中有相同函數名但是有不同參數列表可見函數構成重載關系。內層作用域的函數會隱藏外層的同名函數,同樣的派生類的成員函數會隱藏基類的同名函數。如果要在函數內部調用重名的全局變量則要以“:: va”這樣的形式調用。在編譯器中,編譯器看到的函數名為“類型+名稱+從左往右的參數列表”,但事實上在調用重載函數時,僅僅有返回類型不同是不能成立的,因為編譯器無法判斷你調用的是哪個函數,具有二義性。

8. 運算符重載

兩種重載方式的比較:

一般情況下,單目運算符最好重載為類的成員函數;雙目運算符則最好重載為類的友元函數。 以下一些雙目運算符不能重載為類的友元函數:=、()、[]、->。

類型轉換函數只能定義為一個類的成員函數而不能定義為類的友元函數。 C++提供4個類型轉換函數:reinterpret_cast(在編譯期間實現轉換)、const_cast(在編譯期間實現轉換)、stactic_cast(在編譯期間實現轉換)、dynamic_cast(在運行期間實現轉換,并可以返回轉換成功與否的標志)。

若一個運算符的操作需要修改對象的狀態,選擇重載為成員函數較好。

若運算符所需的操作數(尤其是第一個操作數)希望有隱式類型轉換,則只能選用友元函數。 當運算符函數是一個成員函數時,最左邊的操作數(或者只有最左邊的操作數)必須是運算符類的一個類對象(或者是對該類對象的引用)。如果左邊的操作數必須是一個不同類的對象,或者是一個內部 類型的對象,該運算符函數必須作為一個友元函數來實現。

當需要重載運算符具有可交換性時,選擇重載為友元函數。

注意事項:

除了類屬關系運算符”.“、成員指針運算符”.*“、作用域運算符”::“、sizeof運算符和三目運算符”?:“以外,C++中的所有運算符都可以重載。

重載運算符限制在C++語言中已有的運算符范圍內的允許重載的運算符之中,不能創建新的運算符。 運算符重載實質上是函數重載,因此編譯程序對運算符重載的選擇,遵循函數重載的選擇原則。

重載之后的運算符不能改變運算符的優先級和結合性,也不能改變運算符操作數的個數及語法結構。

運算符重載不能改變該運算符用于內部類型對象的含義。它只能和用戶自定義類型的對象一起使用,或者用于用戶自定義類型的對象和內部類型的對象混合使用時。

運算符重載是針對新類型數據的實際需要對原有運算符進行的適當的改造,重載的功能應當與原有功能相類似,避免沒有目的地使用重載運算符。

9. 繼承和組合

kind of關系下用繼承,part of關系下用組合。

繼承

class Human{ …};class Man : public Human{ …};class Boy : public Man{ …};

組合

class Eye{ public: void Look(void);};class Nose{ public:   void Smell(void);};class Mouth{ public:  void Eat(void);};class Ear{ public:  void Listen(void);};class Head{ public:   void Look(void) { m_eye.Look(); }   void Smell(void) { m_nose.Smell(); }   void Eat(void) { m_mouth.Eat(); }   void Listen(void) { m_ear.Listen(); } private:   Eye m_eye;   Nose m_nose;   Mouth m_mouth;   Ear m_ear;};繼承的關系不同對這個派生類并無影響,而是對該派生類的派生類產生影響。例如private Base(10),則對于該派生類的派生類來說,Base不可見。

10. inline & extern

關鍵字inline 必須與函數定義體放在一起才能使函數成為內聯,僅將inline 放在函數聲明前面不起任何作用。定義在類聲明之中的成員函數將自動地成為內聯函數。宏替換是單純地代碼替換,inline函數真正具有函數的特征。extern 表示該聲明已經定義在別的文件中了。

11. virtual函數與純虛函數

虛函數:類Base中加了Virtual關鍵字的函數就是虛擬函數(例如函數print),于是在Base的派生類Derived中就可以通過重寫虛擬函數來實現對基類虛擬函數的覆蓋。當基類Base的指針point指向派生類Derived的對象時,對point的print函數的調用實際上是調用了Derived的print函數而不是Base的print函數。我們只需在把基類的成員函數設為virtual,其派生類的相應的函數也會自動變為虛函數。也就是說,virtual函數被繼承后可以自動動態綁定當前對象。

純虛函數:只聲明,無定義,包含純虛函數的類稱為抽象類,無實際作用,只作為基類。

class <類名>{virtual <類型><函數名>(<參數表>)=0;…};

重載和覆蓋的區別

重載的幾個函數必須在同一個類中; 覆蓋的函數必須在有繼承關系的不同的類中覆蓋的幾個函數必須函數名、參數、返回值都相同; 重載的函數必須函數名相同,參數不同。覆蓋的函數前必須加關鍵字Virtual; 重載和Virtual沒有任何瓜葛,加不加都不影響重載的運作。

關于C++的隱藏規則:

如果派生類的函數與基類的函數同名,但是參數不同。此時,不論有無virtual 關鍵字,基類的函數將被隱藏(注意別與重載混淆)。如果派生類的函數與基類的函數同名,并且參數也相同,但是基類函數沒有virtual 關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆)。

重寫 重載 重定義

重寫(override): 父類與子類之間的多態性。子類重新定義父類中有相同名稱和參數的虛函數。

1) 被重寫的函數不能是 static 的。必須是 virtual 的 ( 即函數在最原始的基類中被聲明為 virtual ) 。

2) 重寫函數必須有相同的類型,名稱和參數列表 (即相同的函數原型)

3) 重寫函數的訪問修飾符可以不同。盡管 virtual 是 private 的,派生類中重寫改寫為 public,protected 也是可以的

重載 (overload): 指函數名相同,但是它的參數表列個數或順序,類型不同。但是不能靠返回類型來判斷。

重定義 (redefining): 子類重新定義父類中有相同名稱的非虛函數 ( 參數列表可以不同 ) 。

重寫與重載的區別 (override) PK (overload)

方法的重寫是子類和父類之間的關系,是垂直關系;方法的重載是同一個類中方法之間的關 系,是水平關系。

重寫要求參數列表相同;重載要求參數列表不同。

重寫關系中,調用那個方法體,是根據對象的類型(對象對應存儲空間類型)來決定;重載關系,是根據調用時的實參表與形參表來選擇方法體的。

12. binding

對象的靜態類型:對象在聲明時采用的類型。是在編譯期確定的。

對象的動態類型:目前所指對象的類型。是在運行期決定的。對象的動態類型可以更改,但是靜態類型無法更改。

D* pD = new D();//pD的靜態類型是它聲明的類型D*,動態類型也是D* B* pB = pD;//pB的靜態類型是它聲明的類型B*,動態類型是pB所指向的對象pD的類型D* C* pC = new C(); pB = pC;//pB的動態類型是可以更改的,現在它的動態類型是C* 靜態綁定:綁定的是對象的靜態類型,某特性(比如函數)依賴于對象的靜態類型,發生在編譯期。動態綁定:綁定的是對象的動態類型,某特性(比如函數)依賴于對象的動態類型,發生在運行期。只有虛函數是動態綁定,其余函數都是靜態綁定。動態綁定的函數調用的函數體看實際上的對象類型,靜態綁定的函數調用的函數體看聲明的對象類型。虛函數是動態綁定的,但是為了執行效率,缺省參數是靜態綁定的。

13. upcasting、downcasting與類指針

將基類引用轉換為派生類引用稱為upcasting,因為在繼承圖上式上升的。

對于一個使用了虛函數的基類來說:

Base b = d;//直接賦值(產生切割) b.Test(); Base& b2 = d;//使用引用賦值(不產生切割) b2.Test(); Base* b3 = &d;//使用指針賦值(不產生切割) b3->Test(); //覆蓋方法和子類數據丟失的現象生成切割(slice)

14. 模板

模板的一般形式:

Template <class或者也可以用typename T>返回類型 函數名(形參表){//函數定義體 }//template是一個聲明模板的關鍵字,表示聲明一個模板關鍵字class不能省略,如果類型形參多余一個 ,每個形參前都要加class <類型 形參表>可以包含基本數據類型可以包含類類型.template <class T> inline T square(T x) { T result; result = x * x; return result; };

15. 異常探查

http://www.49028c.com/ggjucheng/archive/2011/12/18/2292089.html

16. explicit

Test1 t1=12;//隱式調用其構造函數,成功Test2 t2=12;//編譯錯誤,不能隱式調用其構造函數Test2 t2(12);//顯式調用成功

explicit可以避免隱式調用構造函數。

17. 友元函數

class A{ friend int print(); //友元函數不可被繼承}int print(){}; //可以定義在類內或者類外int main{ A obj; print(); //可以直接調用友元函數}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色综合亚洲精品激情狠狠| 日韩电影中文字幕av| 亚洲mm色国产网站| 97在线观看视频| 亚洲免费小视频| 亚洲毛片一区二区| 欧美视频第一页| 欧美激情在线有限公司| 日韩av在线免费| 欧美成人激情图片网| 国产香蕉精品视频一区二区三区| 亚洲缚视频在线观看| 国产ts一区二区| 亚洲国产日韩精品在线| 97精品一区二区三区| 日韩在线观看免费全集电视剧网站| 人妖精品videosex性欧美| 91精品国产高清久久久久久久久| 亚洲日韩中文字幕在线播放| 午夜精品久久久久久99热| 国产精品视频1区| 欧美性极品少妇精品网站| 国产精品视频一| 日韩欧美主播在线| 欧美性极品xxxx娇小| 亚洲精品wwwww| 国产一区二区美女视频| 91久热免费在线视频| 成人妇女免费播放久久久| 亚洲激情久久久| 成人午夜高潮视频| 国产日韩欧美中文| 亚洲视频在线观看网站| 国产精品羞羞答答| 欧美性生活大片免费观看网址| 91国产精品视频在线| 精品久久久av| 国内外成人免费激情在线视频| 欧美日韩免费区域视频在线观看| 欧美俄罗斯乱妇| 国产精品福利观看| 中文字幕欧美精品日韩中文字幕| 亚洲va男人天堂| 欧美日韩国产二区| 日韩av在线看| 韩剧1988免费观看全集| 秋霞成人午夜鲁丝一区二区三区| 久久精品一本久久99精品| 日韩精品在线电影| 亚洲欧美中文字幕在线一区| 91av在线播放视频| 国产在线精品自拍| 伦伦影院午夜日韩欧美限制| 欧美成人激情视频免费观看| 久久影视三级福利片| xxx一区二区| 国产成人综合亚洲| 精品久久久久久中文字幕大豆网| 久久精品国产69国产精品亚洲| 九九精品在线视频| 亚洲精品动漫久久久久| 亚洲午夜国产成人av电影男同| 精品久久久久久电影| 中文字幕日韩有码| 欧美日韩精品在线视频| 粉嫩老牛aⅴ一区二区三区| 国产成人福利夜色影视| 欲色天天网综合久久| 91福利视频在线观看| 日韩欧美高清在线视频| 91伊人影院在线播放| 最近2019中文字幕大全第二页| 精品国产31久久久久久| 91在线无精精品一区二区| 久久亚洲精品小早川怜子66| 欧美午夜宅男影院在线观看| 91久久久久久久久久久| 欧洲永久精品大片ww免费漫画| 久久精品美女视频网站| 亚洲自拍另类欧美丝袜| 国内伊人久久久久久网站视频| 日本精品视频网站| 亚洲欧美激情一区| 精品无人国产偷自产在线| 黑人巨大精品欧美一区免费视频| 在线观看欧美日韩国产| 国产精品久在线观看| 国产在线观看精品| 国产精品第2页| 国语自产精品视频在免费| 久久人人97超碰精品888| 国产精品视频永久免费播放| 日韩欧美亚洲成人| 日韩色av导航| 91免费看国产| 福利微拍一区二区| 九九视频直播综合网| 日韩在线视频导航| 欧美韩国理论所午夜片917电影| 亚洲综合国产精品| 久久九九亚洲综合| 免费97视频在线精品国自产拍| 中文在线资源观看视频网站免费不卡| 成人a级免费视频| 粉嫩av一区二区三区免费野| 色婷婷av一区二区三区在线观看| 亚洲欧美一区二区三区在线| 原创国产精品91| 自拍偷拍亚洲欧美| 日韩美女免费线视频| 欧美精品国产精品日韩精品| 国产精品自拍网| 日韩精品视频免费专区在线播放| 日韩欧美一区二区在线| 日本一区二区在线播放| 国产日韩欧美在线视频观看| 欧美日韩亚洲精品内裤| 成人做爰www免费看视频网站| 久久久精品中文字幕| 国产成人91久久精品| 亚州国产精品久久久| 国产美女精品视频免费观看| 亚洲天堂网在线观看| 色偷偷噜噜噜亚洲男人的天堂| 国产精品久久一区| 成人伊人精品色xxxx视频| 久久精品男人天堂| 欧美成人午夜免费视在线看片| 国产一区二区精品丝袜| 日韩a**中文字幕| 国产精品嫩草影院一区二区| 懂色av影视一区二区三区| 亚洲精品动漫久久久久| 亚洲最大福利视频网站| 国产精品88a∨| 成人网在线观看| 亚洲日韩第一页| 欧美做受高潮1| 日韩成人激情视频| 亚洲人精品午夜在线观看| 国产美女久久精品| 成人免费午夜电影| 亚洲精品久久久久久久久| 亚洲国产黄色片| 福利视频一区二区| 国产精品高潮粉嫩av| 亚洲高清久久久久久| 日产精品久久久一区二区福利| 欧美孕妇与黑人孕交| 国产精品高潮呻吟久久av野狼| 国产精品美女主播| 中文字幕精品av| 亚洲欧美中文日韩在线| 日韩有码在线电影| 久久人人爽人人爽人人片亚洲| 精品国产欧美成人夜夜嗨| 日韩欧美国产激情| 在线观看中文字幕亚洲| 欧美一区三区三区高中清蜜桃| 成人激情免费在线| 久久视频免费在线播放| 91网站免费观看| 日韩电视剧免费观看网站| 亚洲人成网站色ww在线|