---
# System prepended metadata

title: C++ 入門學習

---

# 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;
}

```