# C++ 入門學習 以 class 創建類別: ```cpp= class Node{ public: int data; Node* left; Node* right; // 構造函數 Node() : data(0), left(nullptr), right(nullptr){} Node(int x): data(x),left(nullptr), right(nullptr){} }; Node* myNode = new Node(5); ``` 不用構造函數所定義的方法 ```cpp= class node{ public : int data; node* left; node* right; }; node* newNode(int data){ node* Node = new node(); Node->data = data; Node->left = nullptr; Node->right = nullptr; return(Node); } int main(){ node* root = newNode(1); root->left = newNode(2); root->right = nweNode(3); } ``` 用 struct 創建: ```cpp= struct ListNode{ int val; ListNode* next; ListNode(int x): val(x), next(NULL){} }; ``` 如果不提供任何構造函數,編譯器會提供一個默認的構造函數,這個默認構造函數不會初始任何成員變數,如果省略這個構造函數就需要在創建每個 ListNode 對象後手動設置這些值。 ```cpp= struct ListNode{ int val; ListNode* next; }; int main(){ ListNode node; node.val = 5; node.next = NULL; } ``` ## 封裝 物件導向中用來實作資訊隱藏的機制,確保物件的安全。其作法為:隱藏不想讓外界碰觸的成員,只公開接受外界存取的成員。 private 只允許本類別中的其他成員存取。 protected 允許本類別的子類別存取。 public 允許所有類別存取。(用範例解釋存取) ## 繼承 物件導向中用來避免程式碼重複撰寫與減低維護困難度的機制。子類別可以繼承父類別中的所有成員。也就是說,把多個類別都會用到的成員,寫在父類別中,子類別只要繼承父類別,不必再寫,就可以擁有那群成員。不但避免了程式寫的重複撰寫,也減少了日後維護的困難度。因為若有程式碼要修改,只需要修改一個類別。 當我們寫一個新類別,指定繼承某一個或多個己存在的類別時,就是在使用那一個或多個己存在的類別。新類別稱之為衍生類別 (Derived class) 或子類別 (Child class),己存在的類別稱之為基礎類別 (Base class) 或父類別 (Parent class)。子類別繼承父類別中的所有成員。但繼承了不代表可以存取,子類別不能存取父類別中宣告為 private 的成員,只能存取宣告為 protected 或 public 的成員。 當你是類別開發者時,不接受子類別與物件存取的,宣告為 private。不接受物件存取,但接受子類別存取的,宣告為 protected。接受物件存取的才宣告為 public。 繼承運算符號 : ## 建構函式 物件建立時,環境會在配置記憶體之後呼叫類別中定義的建構函式。類別開發者會在建構函式中撰寫物件初始化的程式碼,一般是指定資料成員的初值。建構函式的名稱必須與類別名稱一樣,可以有參數列,但不可以有返回型別。參數列可以宣告參數預設值。 預設的建構函式 建立物件時,若建立物件的敍述中沒有指定建構函式。環境預設會呼叫沒有參數的建構函式。所以沒有參數的建構函式就是預設的建構函式。 類別中若沒有撰寫建構方法,編譯器會自動產生沒有參數的建構方法。但是,自動產生的建構方法並不會自動指派資料成員的初值,所以建構出來的物件是不安全的。而且,若類別中有撰寫任何建構方法,編譯器就不會自動產生沒有參數的建構方法。 Overloading 建構函式 類別中除了沒有參數的建構函式,也可以視需求,Overloading 多個建構函式。 this 每一個成員函式中都有一個隱含的指標 this。this可以指向呼叫此函式的物件,用來取存物件成員。 主要用途有二: 在專業編輯環境中快速找到要存取的成員 解決成員變數與參數名稱重複的問題。 子類別的建構函式指定呼叫父類別的建構函式 若父類別沒有預設的建構函式或 Overloading 多個建構函式,子類別的建構函式可以指定呼叫。 ## 在 C++ 中,static 和 virtual 函數是面向對象編程中非常重要的概念。 Static 函數 定義: Static 函數屬於類別本身,而不是類別的任何特定對象。這意味著它們可以在不創建類別的實例的情況下被調用。 特點: Static 函數只能訪問類別的 static 成員(變數或函數)。 它們沒有 this 指針,因為它們不是關聯到任何對象。 用途: 常用於創建工具函數或全局與該類型相關的功能。 ```cpp! class Math { public: static int add(int a, int b) { return a + b; } }; int main() { int result = Math::add(5, 3); // 不需要創建 Math 類別的對象 std::cout << "Result: " << result << std::endl; return 0; } ``` Virtual 函數 定義: Virtual 函數允許在衍生類中被重寫。當通過基類的指針或引用調用時,執行哪個版本的函數將在運行時決定(晚綁定)。 特點: Virtual 函數允許多態性,即在衍生類中可以根據需要重寫基類的行為。 如果在基類中有虛擬析構函數,則可以確保通過基類指針刪除衍生類對象時,調用正確的析構函數。 用途: 在實現多態性和動態綁定中非常重要。 ```cpp! class Animal { public: virtual void speak() { std::cout << "Some animal sound" << std::endl; } }; class Dog : public Animal { public: void speak() override { std::cout << "Woof!" << std::endl; } }; int main() { Animal* myDog = new Dog(); myDog->speak(); // 輸出 "Woof!" delete myDog; return 0; } ```