1. 程式人生 > >**C++總結小記**

**C++總結小記**

前些天,寫程式碼發現有些基礎知識都忘的差不多了,有段時間麼有用了,花了些時間查了些資料後,做了個總結: 1、C++中建構函式和解構函式呼叫順序:

建構函式:

基類建構函式-》物件成員建構函式-》派生類建構函式。。。派生類解構函式-》物件成員解構函式-》基類解構函式;

虛擬函式必須是類的成員函式,其中,靜態成員函式和建構函式不能定義為虛擬函式,解構函式可以;

特例:

1、靜態物件:在所在的定義檔案結束時析構;

2、全域性物件:在程式結束後析構;

3、物件成員:先析構類物件,後析構資料成員;

2、const關鍵字:

#const修飾變數:

1 #include 2 using namespace std; 3 int main(){ 4 int a1=3; //non-const data 5 const int a2=a1; //const data 6 7 int * a3 = &a1; //non-const data,non-const pointer 8 const int * a4 = &a1; //const data,non-const pointer 9 int * const a5 = &a1; //non-const data,const pointer 10 int const * const a6 = &a1; //const data,const pointer 11 const int * const a7 = &a1; //const data,const pointer 12 13 return 0; 14 } (1)只有一個const,如果const位於*左側,表示指標所指資料是常量,不能通過解引用修改該資料;

指標本身是變數,可以指向其他的記憶體單元。

(2)只有一個const,如果const位於*右側,表示指標本身是常量,不能指向其他記憶體地址;

指標所指的資料可以通過解引用修改。

(3)兩個const,*左右各一個,表示指標和指標所指資料都不能修改。

#const修飾形參:傳遞過來的引數在函式內不可以改變,與上面修飾變數時的性質一樣。

#const修飾成員函式:

(1)const修飾的成員函式不能修改任何的成員變數(mutable關鍵字修飾例外)

(2)const成員函式不能呼叫非onst成員函式,因為非const成員函式可以會修改成員變數;

1 #include 2 using namespace std; 3 class Point{ 4 public : 5 Point(int _x):x(_x){} 6 7 void testConstFunction(int _x) const{ 8 9 ///錯誤,在const成員函式中,不能修改任何類成員變數 10 x=_x; 11 12 ///錯誤,const成員函式不能呼叫非onst成員函式,因為非const成員函式可以會修改成員變數 13 modify_x(_x); 14 } 15 16 void modify_x(int _x){ 17 x=_x; 18 } 19 20 int x; 21 }; #const修飾成員函式返回型別:

返回形式有兩種:

1、返回函式指標:如果返回const data,non-const pointer,返回值也必須賦給const data,non-const pointer。因為指標指向的資料是常量不能修改。

2、返回值的形式:如果函式返回值採用“值傳遞方式”,由於函式會把返回值複製到外部臨時的儲存單元中,加const 修飾沒有任何價值。所以,對於值傳遞來說,加const沒有太多意義。

【注意】函式寫成const int T(void)和int T(void)等效的;

1 const int * mallocA(){ ///const data,non-const pointer 2 int *a=new int(2); 3 return a; 4 } 5 6 int main() 7 { 8 const int *a = mallocA(); 9 ///int *b = mallocA(); ///編譯錯誤 10 return 0; 11 } 3、類中定義static資料成員、static成員函式:

#static資料成員:

    static資料成員獨立於該類的任意物件而存在,可以直接通過作用域操作符,通過類直接呼叫;或者是像一般資料成員一樣,通過物件、引用、或指向該類型別物件的指標直接呼叫(前提是,static資料成員許可權必須是public,不能是private);

    如果類中定義多個static資料成員,static資料成員初始化的次序是按照static資料成員在類中的宣告次序進行初始化的;

【注意】類中不能給static初始化;如果需要初始化,只能對const int型別初始化,const string等都不行; 例:

class stu { public: static int age; static const int age=20; static const string name=“xiaoming” //error private: … }; 函式中通過作用域操作符來初始化: int Person::age=20; #static成員函式: static成員函式同樣是類的組成部分並不屬於任何物件的組成部分,因此,static成員函式沒有this指標。一般而言,類中的成員函式具有一個附加的隱含實參,即指向該類物件的一個指標。這個隱含實參命名為this。因為static成員函式不是任何物件的組成部分,所以static成員函式就沒有this形參了。 由於成員函式宣告為const說明該成員函式不會修改該成員函式所屬的物件,所以static成員函式不能宣告為const。為什麼呢?因為static成員函式不是任何物件的組成部分。static成員函式可以直接訪問所屬類的static成員,但是不能直接使用非static成員函式!也不能訪問static const 型別的成員! ###Virtual關鍵詞:

虛擬函式、純虛擬函式:實現多型;

虛基類:多重繼承,防止包含多個基類物件,造成資源浪費;

1、虛擬函式:

類Base中加了Virtual關鍵字的函式就是虛擬函式,在Base的派生類Derived中通過重寫虛擬函式來實現對基類虛擬函式的覆蓋。當基類Base的指標指向派生類Derived的物件時,實際呼叫Derived的覆寫函式而不是基類的虛擬函式,這也是面向物件中多型的體現:

總結:基類的物件在呼叫函式時,如果有virtual則根據多型性呼叫派生類的覆寫函式,如果沒有virtual則是正常的靜態函式呼叫,還是呼叫基類的。

2、純虛擬函式:

純虛擬函式可以看只是為子類提供一個介面,其本身是不能例項化的;

總結:包含一個或多個純虛擬函式的類被編譯器識別為抽象基類。抽象基類不能被例項化,一般用於繼承。

3、虛擬繼承: 在多繼承下,虛繼承就是為了解決菱形繼承中,B,C都繼承了A,D繼承了B,C,那麼D關於 A的引用只有一次; 許可權:可以採用public、protected、private三種不同的繼承關鍵字進行修飾; 示例: class A{ void func(){}; }; class B :public virtual A{ void func2(){}; }; 虛繼承:在繼承定義中包含了virtual關鍵字的繼承關係;(繼承修飾中存在關鍵字virtual) 虛基類:在虛繼承體系中的通過virtual繼承而來的基類,(基類存在virtual修飾的函式) 4、C++三大特性:繼承、多型、封裝; 繼承: 繼承可以使得子類具有父類的各種屬性和方法,而不需要再次編寫相同的程式碼,同時,子類也可以定義自己的屬性,或者是重新覆寫父類的某些方法和屬性,使其獲得與父類不同的功能。 多型: 多型是建立在繼承的基礎上;多型性,允許將子類型別的指標賦值給父類型別的指標,多型性在C++中是通過虛擬函式實現的。 虛擬函式就是允許被其子類重新定義的成員函式。而子類重新定義父類虛擬函式的做法,稱為“覆蓋”,或者稱為“重寫”。子類重寫父類中虛擬函式時,即使不用virtual宣告,該過載函式也是虛擬函式。 封裝:

封裝就是隱藏部分關鍵成員,而只是讓小部分成員作為類與外部的介面,而封裝部分只能通過某些特定的方式才能訪問。封裝的目的是增強安全性和簡化程式設計,使用者不必瞭解具體的實現細節,而只是通過外部介面以及特定的訪問許可權來使用類的成員; 5、程序、執行緒與協程: https://www.cnblogs.com/zhang-can/p/7215506.html #程序:一個程式在一個數據集中的一次動態執行過程,是CPU資源分配和排程的獨立單位;可以理解為—正在執行的程式,而資料集表示的是程序執行所需要的資源;注意:程序一般都是由程式、資料集和程序控制塊三部分組成;而程序控制塊是用來記錄下程序外部特徵和描述程序的執行變化過程;系統可以通過它管理程序。 程序的侷限在於建立、撤銷和切換的開銷較大,因此引入執行緒; 父程序與子程序:共享程式碼段,其他所有資源都是複製父程序的一個副本,當然也就不共享地址空間;從而可以理解成父子程序為互不相干的兩個獨立程序;檔案描述符:子程序通過繼承父程序檔案描述符,與父程序共享檔案描述項,即一個程序改變了檔案,另外一個程序也知曉; #執行緒 執行緒,被稱為輕量級程序,是一個基本的CPU執行單元,也是程式執行中最小單元;一個程序可以包含多個執行緒; 執行緒由執行緒ID、程式計數器、暫存器集合和棧四部分組成; 優點:執行緒解決了程序切換開銷大的問題,執行緒在執行中開銷相對小很多,提高了作業系統的併發效能; 缺點:執行緒沒有屬於自己的系統資源,所能做的很有限,但是同一程序中的多個執行緒能共享執行緒資源; 執行緒間共享程序中所有資源,每個執行緒只擁有小部分屬於自己的資源—棧空間;用於儲存執行狀態和區域性自動變數; #協程: 協程被稱為微執行緒,和程序、執行緒作業系統排程不同的是,協程是由使用者控制排程的。 協程關鍵字—yeild,一個子程式入口,通過yield方式轉移執行權的協程之間不是呼叫者與被呼叫者的關係,而是彼此對稱、平等的,通過相互協作共同完成任務。其執行的大致流程如下: 第一步,協程A開始執行。 第二步,協程A執行到一半,進入暫停,通過yield命令將執行權轉移到協程B。 第三步,(一段時間後)協程B交還執行權。 第四步,協程A恢復執行。 協程的特點在於是一個執行緒執行,與多執行緒相比,其優勢體現在:

協程的執行效率非常高。因為子程式切換不是執行緒切換,而是由程式自身控制,因此,沒有執行緒切換的開銷,和多執行緒比,執行緒數量越多,協程的效能優勢就越明顯。 協程不需要多執行緒的鎖機制。在協程中控制共享資源不加鎖,只需要判斷狀態就好了。 Tips:利用多核CPU最簡單的方法是多程序+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的效能。

#程序、執行緒之間關係:

(1)一個執行緒只能屬於一個程序,而一個程序可以有多個執行緒,但至少有一個執行緒;

(2)資源分配給程序,程序是程式的主體,同一程序的所有執行緒共享該程序的所有資源;

(3)cpu分配給執行緒,即真正在cpu上執行的是執行緒;

(4)執行緒是最小的執行單元,程序是最小的資源管理單元;

#並行與併發區別:

並行處理是指計算機系統中能同時執行兩個或多個任務的計算方法,並行處理可同時工作於同一程式的不同方面

併發處理是同一時間段內有幾個程式都在一個cpu中處於執行狀態,但任一時刻只有一個程式在cpu上執行。

併發的重點在於有處理多個任務的能力,不一定要同時;而並行的重點在於就是有同時處理多個任務的能力。並行是併發的子集;

在這裡插入圖片描述這圖是借鑑網上的,覺得方便理解的!