linux c c 知識點整理 三

2021-07-31 02:09:51 字數 2568 閱讀 6555

過載即為函式過載,過載的特徵:

(1)相同的範圍,也就是在同乙個類中

(2)函式名字相同

(3)引數不同

(4)virtual關鍵字無影響

覆蓋是指派生類函式覆蓋基類函式,覆蓋的特徵:

(1)不同的範圍,即函式分別位於派生類和基類

(2)函式名字相同

(3)引數相同

(4)基類函式必須有virtual關鍵字

隱藏是指派生類的函式遮蔽了與其同名的基類函式,特徵如下:

(1)如果派生類的函式與基類的函式同名,但是引數不同,此時不論有沒有virtual關鍵字,基類的函式都將被隱藏

(2)如果派生類的函式與基類的函式同名,引數也相同,但是基類函式沒有virtual關鍵字,此時,基類的函式將被隱藏

總結:函式名相同,引數也相同的情況下,如果基類函式有virtual關鍵字,則是多型,否則就是隱藏;函式名相同,引數不同的情況下,如果函式位於同乙個類中,則是過載,否則就是隱藏。

atexit函式,是註冊終止函式,即main執行結束後呼叫的函式,註冊以後函式將由exit函式自動呼叫,其中atexit註冊的函式型別應該是不接受任何引數的void函式,exit呼叫這些註冊函式的順序與它們登記時候的順序相反。

另外,atexit函式是包含在stdlib.h庫中。

todo:如果**中有該標識,說明在標識處有功能**待編寫, 待實現的功能在說明中會簡略說明;

fixme:如果**中有該標識,說明標識處**需要修正,甚至**是錯誤的,不能工作,需要修復,如何修正會在說明中簡略說明;

***:如果**中有該標識,說明標識處**雖然實現了功能,但是實現的方法有待商榷,希望將來能改進,要改進的地方會在說明中簡略說明。

c**中連用兩個感嘆號表示非非,如果是0,那麼還是0,如果原來是非0,則變為1.

友元關係不能被繼承,友元關係是單向的,友元關係不具有傳遞性。

(1)從包含虛函式的類派生乙個類時,編譯器就為該類建立乙個vtable,其每乙個表項是該類的虛函式位址;

(2)在定義該派生類物件時,先呼叫其基類的建構函式,然後再初始化vptr,最後再呼叫派生類的建構函式(從二進位制的視野來看,所謂基類子類是乙個大結構體,其中this指標開頭的四個位元組存放虛函式表頭指標,執行子類的建構函式的時候,首先呼叫基類建構函式,this指標作為引數,在基類的建構函式中填入基類的vptr,然後回到子類的建構函式,填入子類的vptr,覆蓋基類填入的vptr,如此一來完成vptr的初始化)

(3)在實現動態繫結,不能直接採用類物件,而一定要採用指標或者引用,因為採用類物件傳值方式,有臨時基類物件的產生,而採用指標,則是通過指標來訪問外部的派生類物件的vptr來達到訪問派生類虛函式的結果。

只有當乙個類被用作基類時才需要使用虛析構函式,這樣做的作用是當乙個基類的指標刪除派生類的物件時,能確保派生類的析構函式會被呼叫。因為編譯器它只知道基類指標,呼叫基類析構,並不會主動去呼叫派生類的析構函式,所以基類析構函式需為虛析構函式,這就相當於析構函式的多型。

#ifndef是手動定義巨集名來避免衝突,但#pragma once是編譯器提供保證。

#ifndef是依賴於巨集的名字不能起衝突,可以保證同乙個檔案不會被包含多次,但缺點是如果不同標頭檔案的巨集名不小心撞車了,可能就會導致標頭檔案命名存在,但編譯器卻報找不到宣告的情況。

#pragma once由編譯器自動提供保障,同乙個物理上的檔案不會被包含多次,就是內容相同,但只要是兩個檔案,都會分別包含,但如果乙個標頭檔案被拷貝了多份,這種方法就不能保證檔案不被重複包含。

#ifndef語法移植性好,#pragma once可以避免名字衝突。

#ifdef asimovlib_exports

#define asimovlib_api __declspec(dllexport)

#else

#define asimovlib_api __declspec(dllimport)

#endif

_declspec(dllexport):

宣告乙個匯出函式,是說這個函式要從本dll匯出。我要給別人用。一般用於dll中省掉在def檔案中手工定義匯出哪些函式的乙個方法。當然,如果你的dll裡全是c++的類的話, 你無法在def裡指定匯出的函式,只能用dllexport匯出類。

__declspec(dllimport):

宣告乙個匯入函式,是說這個函式是從別的dll匯入,我要用,一般用於使用某個dll的exe中。

不使用__declspec(dllimport)也能正確編譯**,但使用__declspec(dllimport)使編譯器可以生成更好的**。編譯器之所以能生成更好的**,是因為它可以確定函式是否存在於dll中,這使得編譯器可以生成跳過間接定址級別的**,而這些**通常會出現在跨dll邊界的函式呼叫中。但是,必須使用__declspec(import)才能匯入dll中使用的變數。

explicit用來防止由建構函式定義的隱式轉換,比如:class base base=10;即base類只有乙個int型別的變數,explicit使用了以後,就不允許這樣寫。

被宣告為explicit的建構函式通常比非explicit的建構函式更受歡迎,因為它們禁止編譯器執行非預期的型別轉換。除非我有個好理由允許建構函式被用於隱式型別轉換,否則我會把它宣告為explicit。

linux c c 知識點整理 一

在c 中,申請動態記憶體是使用new和delete,這兩個關鍵字實際上是運算子,並不是函式。而在c中,申請動態記憶體則是使用malloc和free,這兩個函式是c的標準庫函式,使用它們必須包含stdlib.h,才能編譯通過。new delete和malloc free的相同之處在於,new和mall...

linux c c 知識點整理 四

當實際長度不夠時,右對齊 如果字串或者整數的長度超過說明的場寬,則按其實際長度輸出 如果是浮點數,若整數部分超過了說明的整數字場寬,則按其實際長度輸出,若是小數部分超過了說明的小數字場寬,則按說明的寬度以四捨五入輸出。例如 printf d d d n a,b,c b,c 那麼將輸出才c,b,c這3...

js知識點整理 三

啥是閉包?閉包就是把某個變數或者函式給包裝起來 我們js當中會接觸很多的全域性變數,那如何保證我們的區域性變數在執行完函式之後還存在在我們的記憶體當中呢?就可以使用閉包 閉包總的來說是實現了作用域,使得程式能夠設計出更合理的,有層次的js 實現閉包的方式 function f1 nadd 沒有使用 ...