# 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() ```