---
# System prepended metadata

title: C++
tags: [code]

---

# C++ Learning
> 前面語法都和 C 一樣，憑感覺寫吧～

[TOC]

---

## Class
### **class 定義**
> *寫在”名稱.h“檔中*
```C++=
class class_Name{
    //預設private
    int var_Name
    .
    .
    .
    public:
    
    //特殊function
    class_Name(參數列);   //建構子
    ~class_Name();       //解構子
    
    //function
    return_dateType function_Name(參數列)
    void function_Name(參數列);
}
```
:::info
### **建構子與解構子**
#### 建構子與解構子可由系統自行產生
> *建構子就是建構時初始化的function*
> *可輸入參數列*
> *設定預設值*
```C++
class_Name(參數列);   //class_Name == function_Name
```
> *解構子是function結束前執行*
> *不可輸入參數列*
```C++
~class_Name();   //class_Name == function_Name
```
:::

---
:::info
### **複製建構子**
> *參數列為 class*
> *可更改設定預設值*
```C++
class_Name(class_Name &); 
```
```C++
//盡量加 const，避免改動原 class
class_Name(const class_Name &t){  
    hrs = t.hrs;
    min = 0;  //可以更改複製建構子
}
```
:::

---

### **func 定義**
> *寫在”名稱.cpp“檔中*
```C++=
#include <iostream>
#include "名稱.h"
using namespace std;

return_dateType class_Name::function_Name(){
...
}

void class_Name::function_Name(){
...
}
```


---

### **main with class**
> 生成物件

```C++
class_Name item_Name(依照建構子需求);
```
> main中呼叫function

```C++
item_Name.function_Name(依照function需求)
class_Name::function_Name(...)  //static
```
> 物件消失順序：後進先出

---
:::info
### **const and static**
#### const
> 在 class 中的 const
```C++=
class class_Name{
    const int i;
    .
    .
public:
    void function() const;
}
```
>建構子中建構 const var
```C++
class_Name::class_Name():i(const_num){
    ...
}
```
#### **static**
> class 中的 static
> 全部 class 共用一個變數
> 
> 在 Class 中，static 關鍵字用於聲明靜態成員變數。靜態成員變數是屬於類本身而不是類的特定物件實例的成員變數。每個類的靜態成員變數僅有一個實例，它在程式生命週期中存在於整個類的範圍內，不隨物件的建立和銷毀而改變。

```C++=
class ClassName {
    static int staticVar;
public:
    static void staticFunction();
};
```
> 靜態成員變數必須在類外部進行初始化。這樣做確保了靜態成員變數僅有一個實例並且被正確初始化。
```C++
int ClassName::staticVar = 0; // 在類外部初始化靜態成員變數
```
```C++
void ClassName::staticFunction() {
    // 在靜態成員函數中可以訪問靜態成員變數
    staticVar = 10;
}
```
>而 static const 可以直接初始化
```C++
class a{
    static const aa = 0;
}
```
:::
---

## Pointer
#### 簡單來說，就跟 C 的 Pointer 一樣～
#### * : 求地址的值
#### & : 求值的地址
---
> 例子 1
```C++=
#include <iostream>
using namespace std;

void func(int *p){
    cout << *p << endl;
    *p = 100;
}

int main(){
    int a = 10;
    //pointer to a
    int *p = &a;
    cout << *p << endl;
    func(p);
    //a is changed by func
    cout << *p << endl;
    return 0;
}
```
>output:
```=
10
10
100
```
---
>例子 2
```C++=
#include <iostream>
using namespace std;

void func(int a, int **pp){
    a = 10;
    **pp = 100;
    cout << a <<" "<< **pp << endl;
}

int main(){
    int a = 10;
    int *p = &a;
    int **pp = &p;
    func(a, pp);
    cout << a <<" "<< **pp << endl;

    if(a == **pp)
        cout << "a and **pp are the same" << endl;
    else
        cout << "a and **pp are different" << endl;
        
    return 0;
}

```
>output:
```=
10 100
100 100
a and **pp are the same
```
---
### Array with Pointer
#### 一維陣列
> 如在 int arr[5] 中
> arr = &arr[0]
> arr + 1 = &arr[0]+size(int) = &arr[1]
```C++=
#include <iostream>
using namespace std;

int main(){
    int a[5] = {1, 2, 3, 4, 5};
    //a is the address of the first element
    cout << a << endl;
    //&a[0] is the address of the first element
    cout << &a[0] << endl;
    //a[0] is the first element
    cout << a[0] << endl;
    //*a is the first element
    cout << *a << endl;
    //a+1 is the address of the second element
    cout << a[1] << endl;
    cout << *(a+1) << endl;
    //a+1 is the address of the second element
    cout << a+1 << endl;
    //a+2 is the address of the third element
    cout << a[2] << endl;
    cout << *(a+2) << endl;
    //a+3 is the address of the fourth element
    cout << a[3] << endl;
    cout << *(a+3) << endl;
    //a+4 is the address of the fifth element
    cout << a[4] << endl;
    cout << *(a+4) << endl;
    return 0;
}
```
#### output:
```
0x16ce2b190
0x16ce2b190
1
1
2
2
0x16ce2b194
3
3
4
4
5
5
```
---

## Reference
### reference 定義
#### 類似於取別名
> 將新增一個變數名指向另一個變數
```C++=
#include <iostream>
using namespace std;

int main(){
    int a = 10;
    int &b = a;
    cout << a << " " << b << endl;
}
```
#### output:
```=
10 10
```
---
### Call by Reference
#### 可從 function 改 main 中的變數
```C++=
#include <iostream>
using namespace std;

void func(int a, int &b){
    b = 100;
    cout<< a << " " << b << endl;
}

int main(){
    int a = 10;
    func(a, a);
    cout << a << endl;
}
```
#### output:
```=
10 100
100
```
---
## 雜項
### Inhence
#### Student:
父 Class:
```C++=
class people(){
    int age;
    int height;
    int weight;
public:
    void walk();
    void jump();
}
```
子 Class:
```C++=
class student() : public people{  //繼承 people class
    string school;
    int score;
public:
    void test();
}
```
#### Time:
父 Class:
```C++=
Time::Time(int initHrs,int initMin,int initSec){

}
void Time::Set(h, m, s){

}
```
子 Class:
```C++=
ExtTime::ExtTime(int initHrs, int initMin, int initSec):private Time(initHrs, initMin, initSec){

}

void ExtTime::Set(h, m, s){
    Time::Set(h, m, s);
}

```
---
> 在 子 Class 繼承時，在 父 Class 前的 "public", "protected", "private"，是指繼承後對於子Class的型態。但仍會以較嚴格形式存取，如 父 Class 中的 "protected" 被子 Class 以 "public" 存取時，會以 "protected"形式存取。
> 而 父 Class 中的 private 不會被 子 Class 繼承。

---
#### inline
#### global var 存取
> 直接取變數時，會以最近的初始化輸出。
> 但加上 "::" ，會取全域變數
``` C++=
int a = 9;
int main(){
    int a = 8;
    cout << a;
    cout << ::a;
}
```
---
### Function Operator vs. Function Template
> 同樣允許 function 同名
---
#### Function Operator -> Over loading
> 概念相同，實際操作不同
> 區分條件：參數列不同
> 定義符號
```C++=
int operator$(int a, int b){
    return a + b;
}
```
```C++=
cout << a$b << endl;
```
#### Function Template
> 概念相同，實際操作相同，只有操作的資料類型不同
> 區分條件：參數列的資料型態不同
> 使用：定義一個替代符號以替換不同型態，如＠可以替換為 int, float, string 等型態
```C++=
template <typename 符號>
符號 square(符號 x){
    return x*x;
}

int main(){
    cout << square(3) << endl;
    cout << square(3.3) << endl;
}

```
---
### This
> this 是 pointer
> 藉由回傳自己，達到連續 function
> 
time.cpp
```C++=
    Time Time::PrintHrs(){
        cout<<hour<<":";
        return *This
    }
    Time Time::PrintMin(){
        cout<<min<<":";
        return *This
    }
    Time Time::PrintSec(){
        cout<<sec<<":";
        return *This
    }
```
main.cpp
```C++=
time.PrintHurs().PrintMin().PrintSec();
```
---
### Friend
> 可存取 private 的一個 global function
> 建於 Class 中

```C++=
Class className{
    friend void SetX(className &c, int n)
        c.x = n
    }
private:
    int x;
public:
    getX(...)
```
```C++=
className test();
SetX(&test, 3)
test.getX();
```
---
### vector
> 類似 array，但不需建構時定義固定空間

```C++=
vector<int> a;
vector<int> a(4);  //declare a vector of 4 space
vector<int> a(4, 100); //four ints with value 100
vector<char> letters(25, 'A'); // 'A'x25
vector<int> a(b);      //copy by b

```

```C++=
a.push_back(3);
a.pop_push;
```
> vector clear vs. empty
> empty: 是否為空
> clear: 清空
```C++=
a.empty //return true/flase
a.clear //Empty the vector
```

capacity()
> vector 在使用者 push or pop 時，會自動要記憶體或還記憶體給系統，capacity 是最少留存的記憶體量

swap
> 互換 vector 內容

---

### 二維 vector

```C++=
vector<vector<int>> v2;
```
push_back
ex1:
```C++=
for(int i = 0; i < n; i++){
    vector<int> v1;
    v2.push_back(v1);
}
```
ex2:
```C++=
for(int i = 0; i < 5; i++){
    vector<int> v1(3, 4); //3個4
    v2.push_back(v1);
}
```
v2:
```=
444
444
444
444
444
```

輸出：
二維輸出：
```C++=
typedef vector<int> intvec;

void PrintVec(){

}
```

---
### set

---
### map

---
new, delete
init father, const

---

### : vs ::

:  是繼承
:: 是 static function 使用時使用，以及全域變數取用

---
## Container
### vector
#### iterator
> vector 中一個接一個的串列
``` C++=
vector<int>::iterator it;
it = V.begin();  // -> V.end()
it = V.rbegin();  // -> V.rend()

```
### set
> 有排序
```C++=
int names[] = {1, 2, 3, 4, 5}
set<int> nameSet(names, names+5)
nameSet.insert(6);
nameSet.erase(3);
set<int>::iterator it;

```

### map
> key, value

```C++=
string name[] = {"A", "B", "C"};
int numbers[] = {2334, 23132, 4342};
map<string, int> phonebook;
map<string, int>::iterator it;
cout << phonebook[names[2]];
cout << (*it).first << "'s phone number is " << (*it).second << endl;
```
---
## File

---
## 繼承問題
#### 繼承：class A -> class B -> class C

```C++=
void TryMe(A* obj){}

TryMe(&obj); 
// obj 可以輸入 A, B, C class 的東西，因為都有繼承到 class A
```
--
#### 假設 class A, B, C 都有 CallMe function
```C++=
void TryMe(A* obj){
obj.CallMe()
}
// 都是呼叫 A 的 CallMe
```
--
#### 若是要呼叫到自己的 CallMe 則要達成 Dymatic
#### dymatic: virtual

```C++=
class A{
virtual void CallMe();
// 加入 virtual 後，就不會直接叫 A 的 function，會等到執行後判斷
}
```

--

#### if 
```C++=
void TryMe(B* obj){
 obj.CallMe();
}

class A{
 virtual void CallMe();
}

class B :: A{
void CallMe();
}

class C :: B{
 void CallMe();
}

C oC;

TryMe(&obj oC){}
// 依舊會呼叫 C 的 CallMe()

```