2020年7月8日 星期三

工程師的C++筆記

【名稱空間】

如果應用程式是多個團隊共同合作,如果沒有定義名稱空間,名稱預設都是位於全域名稱空間,以類別定義來說,那麼若 A 部門寫了個 Account 類別,B 部門寫了個 Account 類別,當他們要將應用程式整合時,就會發生名稱衝突的問題。

C++ 可以使用 namespace 來定義名稱空間,例如,可以在 account.h 中定義 bank 名稱空間:
namespace bank {
using namespace std; 

    class Account { 
    private:
        string id;  
        string name; 
        double balance;

    public: 
        Account(string id, string name, double balance);
    };
}


在 account.cpp 可以開啟 bank 名稱空間,並在其中實作類別定義:
#include "account.h"

namespace bank {
    using namespace std;

    Account::Account(string id, string name, double balance) {
        this->id = id;
        this->name = name;
        this->balance = balance;
    }
}

名稱空間會是類別名稱的一部份,因此在使用時,必須包含 bank 前置:
bank::Account acct = {"123-456-789", "Justin Lin", 1000};

或者是使用 using 來指明使用哪個名稱空間,例如:
using namespace std;
using namespace bank;

【Public、Protected、Public成員及繼承的用法】

第一: private,public,protected的訪問範圍:
  • private: 僅能由該類中的函數、其朋友函數訪問,不能被不論什麽其它訪問。該類的對象也不能訪問.
  • protected: 能夠被該類中的函數、子類的函數、以及其朋友函數訪問,但不能被該類的對象訪問
  • public: 能夠被該類中的函數、子類的函數、其朋友函數訪問,也能夠由該類的對象訪問
  • 註:朋友函數包含兩種:設為朋友的全局函數,設為朋友類中的成員函數

第二:類的繼承後方法屬性變化:
  • 使用private繼承,父類的全部方法在子類中變為private;
  • 使用protected繼承,父類的protected和public方法在子類中變為protected,private方法不變;
  • 使用public繼承,父類中的方法屬性不發生改變;

三種訪問權限
  • public:能夠被隨意實體訪問
  • protected:僅僅同意子類及本類的成員函數訪問
  • private:僅僅同意本類的成員函數訪問


三種繼承方式
  • public 繼承
  • protect 繼承
  • private 繼承

組合結果

基類中 繼承方式 子類中

public & public繼承 => public

public & protected繼承 => protected

public & private繼承 = > private


protected & public繼承 => protected

protected & protected繼承 => protected

protected & private繼承 = > private


private & public繼承 => 子類無權訪問

private & protected繼承 => 子類無權訪問

private & private繼承 = > 子類無權訪問


由以上組合結果能夠看出

1、public繼承不改變基類成員的訪問權限

2、private繼承使得基類全部成員在子類中的訪問權限變為private

3、protected繼承將基類中public成員變為子類的protected成員,其他成員的訪問 權限不變。

4、基類中的private成員不受繼承方式的影響,子類永遠無權訪問。

此外,在使用private繼承時。還存在第二種機制準許訪問 。

我們已經知道,在基類以private方式被繼承時,其public和protected成員在子類中變為private成員。然而某些情況下,須要在子類中將一個或多個繼承的成員恢復其在基類中的訪問權限。


C++支持以兩種方式實現該目的
  • 方法一。使用using 語句,這是C++標準建議使用的方式
  • 方法二,使用訪問聲明。形式為 base-class::member;。 位置在子類中適當的訪問聲明處。(註。僅僅能恢復原有訪問權限。而不能提高或減少訪問權限)

【friend class 的用法】

要讓類別A存取類別B放在private區域的類別成員,可以使用朋友宣告(friend declaration)。

【虛擬函式】

1.虛擬函式的概念

在語法上,只要在成員函式前加上virtual,例如:virtual void draw() const =0;

所謂繼承其實就是繼承函式的呼叫權。子類可以呼叫父函式的函式。

但是當我們子類要去修改這個函式,則要用到虛擬函式。

 2.虛擬函式的分類:

(1):non-virtual:你不希望derived class overide(重寫)。 int objectID() const; 

(2):virtual函式:你希望derived class去重新override。並且父類有預設的定義。 virtual void erro (const std::string& msg);

(3):pure virtual(純虛擬函式):你希望derived class一定要去重新override它,它對於子類沒有預設定義。virtual void draw(0 const = 0;

重載(Overload)可以使用一個函式名稱來執行不同的實作,但參數不同,這是一種「編譯時期」就需決定的方式,這是「早期繫 結」(Early binding)、「靜態繫結」(Static binding),因為在編譯時就可以決定函式的呼叫對象,它們的呼叫位址在編譯時就可以得知。

「虛擬函式」(Virtual function)可以實現「執行時期」的多型支援,是一個「晚期繫結」(Late binding)、「動態繫結」(Dynamic binding),也就是指必須在執行時期才會得知所要調用的物件或其上的公開介面。

當子類別中定義了一個和父類別相同名稱、相同參數的函式,只有函式的內容不同時,感覺也是一種重載,這需要再確認?實際上執行的結果是:當子類別的該函式存在,則執行該函式;當子類別的該函式不存在,則執行父類別的該函式。







沒有留言:

張貼留言