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