虛函數:
- 在基類用virtual聲明成員函數爲虛函數。
這樣就可以在派生類中重新定義此函數,爲它賦予新的功能,並能方便地被調用。在類外定義虛函數時,不必再加virtual。 - 在派生類中重新定義此函數,要求函數名、函數類型、函數參數個數和類型全部與基類的虛函數相同,並根據派生類的需要重新定義函數體。
C++規定,當一個成員函數被聲明爲虛函數後,其派生類中的同名函數都自動成爲虛函數。因此在派生類重新聲明該虛函數時,可以加virtual,也可以不加,但習慣上一般在每一層聲明該函數時都加virtual,使程序更加清晰。如果在派生類中沒有對基類的虛函數重新定義,則派生類簡單地繼承其直接基類的虛函數。 - 定義一個指向基類對象的指針變量,並使它指向同一類族中需要調用該函數的對象。
- 通過該指針變量調用此虛函數,此時調用的就是指針變量指向的對象的同名函數。
通過虛函數與指向基類對象的指針變量的配合使用,就能方便地調用同一類族中不同類的同名函數,只要先用基類指針指向即可。如果指針不斷地指向同一類族中不同類的對象,就能不斷地調用這些對象中的同名函數。這就如同前面說的,不斷地告訴出租車司機要去的目的地,然後司機把你送到你要去的地方。
純虛函數:
1、 將成員函數聲明爲virtual
2、 後面加上 = 0
3、 該函數沒有函數體, 它的實現留給該基類的派生類去做
例如 :virtual void OnCommand(char* cmdline) = 0;
抽象類:
含有純虛函數的類叫做抽象類(純虛類),抽象類是一種特殊的類,它是爲了抽象和設計的目的而建立的,它處於繼承層次結構的較上層。
抽象類不能被實例化,即無法創建該類的對象。抽象類只能作爲基類來使用,其純虛函數的實現由派生類給出。如果派生類沒有重新定義純虛函數,而派生類只是繼承基類的純虛函數,則這個派生類仍然還是一個抽象類。如果派生類中給出了基類純虛函數的實現,則該派生類就不再是抽象類了,它是一個可以建立對象的具體類了。
接口:
接口描述了類的行爲和功能,而不需要完成類的特定實現。
面向對象的系統可能會使用一個抽象基類爲所有的外部應用程序提供一個適當的、通用的、標準化的接口。然後,派生類通過繼承抽象基類,就把所有類似的操作都繼承下來。
外部應用程序提供的功能(即公有函數)在抽象基類中是以純虛函數的形式存在的。這些純虛函數在相應的派生類中被實現。
這個架構也使得新的應用程序可以很容易地被添加到系統中,即使是在系統被定義之後依然可以如此。
函數重載和運算符重載:
C++ 允許在同一作用域中的某個函數和運算符指定多個定義,函數重載則同名函數的參數不同
運算符重載:Box operator+(const Box&);(其中operator是關鍵字)
C++ 動態內存:
- 棧:在函數內部聲明的所有變量都將佔用棧內存。
- 堆:這是程序中未使用的內存,在程序運行時可用於動態分配內存。
new 和 delete :double* pvalue = NULL;
pvalue = new double; // 爲變量請求內存 new char[20](數組)
delete pvalue; // 釋放內存 delete [] array(數組)
多線程:
多線程是多任務處理的一種特殊形式,多任務處理允許讓電腦同時運行兩個或兩個以上的程序。一般情況下,兩種類型的多任務處理:基於進程和基於線程。
- 基於進程的多任務處理是程序的併發執行。
- 基於線程的多任務處理是同一程序的片段的併發執行。
創建線程: #include <pthread.h> pthread_create (thread, attr, start_routine, arg) //參數依次是:創建的線程id,線程參數,調用的函數,傳入的函數參數 int ret = pthread_create(&tids[i], NULL, say_hello, NULL);
終止線程: pthread_exit (status)
預處理器:
預處理器是一些指令,指示編譯器在實際編譯之前所需完成的預處理。
所有的預處理器指令都是以井號(#)開頭,只有空格字符可以出現在預處理指令之前。預處理指令不是 C++ 語句,所以它們不會以分號(;)結尾。比如 #include、#define、#if、#else、#line 等
#define MIN(a,b) (a<b ? a : b) 將 MIN(a,b) 換爲(a<b ? a : b)
# 運算符會把 replacement-text 令牌轉換爲用引號引起來的字符串。#define MKSTR( x ) #x 相當於將x變爲 ‘x’傳入
## 運算符用於連接兩個令牌 #define CONCAT( x, y ) x ## y 相當於CONCAT( xy ) (假定xy=100, 則結果就相當於100)