# Cpp-0-1-Resource
github 上看到的 [C++ 學習教材](https://github.com/AnkerLeng/Cpp-0-1-Resource/blob/master/%E7%AC%AC3%E9%98%B6%E6%AE%B5-C%2B%2B%E6%A0%B8%E5%BF%83%E7%BC%96%E7%A8%8B%20%E8%B5%84%E6%96%99/%E8%AE%B2%E4%B9%89/C%2B%2B%E6%A0%B8%E5%BF%83%E7%BC%96%E7%A8%8B.md),第 1,2 部分太簡單,我從第 3 開始看,已經很熟的會略過
###### tags: `learning`
## Memory mapping model
* 執行前
* 代碼區
* 指令
* 唯讀
* 共享
* 資料區
* constant data
* static data
* 執行後
* stack
* local data
* handle function
* process manage
* heap
* allocate
* free
## new operator
* allocate
* new
* 要新空間同時會呼叫 constructor
* malloc
* 單純給出空間
* free
* delete
* 釋放空間同時會呼叫 destructor
* free
* 單純釋放空間
## reference
### reference VS pointer
* reference
* 別名
* 背後的實作用 const pointer
* 必須初始化
* 無法更改別名
* 解釋:
```c++=
int a;
int &b = a;
// b 不是 a 的副本, b 就是 a
// 修改 b 等於 修改 a
```
* pointer
* 變數地址
* 與 refernce 相比,要多一個 dereference
### reference 使用
* 簡化操作:
* reference version
```c++
void swap(int &a, int &b)
{
int tmp = b;
b = a;
a = tmp;
}
int main()
{
int a = 1;
int b = 2;
swap(a, b);
}
```
* pointer version
```c++
void swap(int *a, int *b)
{
int tmp = *b;
*b = *a;
*a = tmp;
}
int main()
{
int a = 1;
int b = 2;
swap(&a, &b);
}
```
* as a function return value
* 別回傳 local value
* function 做為 left value ,猜測可能是 function 調用等同於別名,對其賦值等同對別名賦值
```c++
int &foo()
{
static int a;
a = 10;
return a;
}
int main()
{
int b = foo();
foo() = 100;
}
```
### 本質
前面提過,基本就是 compiler 會把他弄成 constant pointer ,對別名操作實際上都是透過這個 const. pointer
```c++
// compiler 自動將其改為 int* const ref = a
void foo(int &a)
{
a = 0xdeadbeef;
}
int main()
{
int a = 10;
// compiler 修正為 int const *ref = &a;
int &ref = a;
// *ref = 100;
ref = 100;
foo(a);
}
```
### const reference
主要是用來防止操作錯誤,具體不表
## class
### class member 權限問題
cpp class 內主要有三種權限:
* public
* 大家都可以存取、使用
* private
* 只有內部 function 可以使用
* protected
* 只有內部 function 和繼承的 class 可以在內部使用
所以說 protected 可以算是追加繼承版本的 private (之前一直沒弄懂)
### constructor and destructor
* constructor/destructor
* 負責初始化/清理
* 沒有實作則編譯器提供空實作
* destructor 會自己呼叫
* constructor
* 同 class name
* 可以 overloading
* 沒有 return value, 也沒有 void
* 只會 call 一次
* 直接建立 class 則 constructor 會自動呼叫
* destructor
* ~class_name()
* 沒有 overloading
* 沒有 return value, 也沒有 void
* 只會 call 一次
### constructor 分類
* 依參數分類
* 無參數
* 可以自己實作
* 沒有實作則由編譯器提供
* 有參數
* 就是有參數...
* 依類型分類
* 普通類型
* 上面那種就是普通類型
* 拷貝類型
* 參數為同 class 的 object
```c++
class Obj
{
Obj(const Obj &o2){member = o2.member;}
};
```
### constructor 調用方式
* 無參數調用
```c++
Object o1;
Object o1 = Object();
```
原先以為 `Object o1()` 也是無參數調用,結果什麼鬼也沒發生,看來應該不是...
* 括號法
```c++
Object o1(1);
```
* 顯示法
```c++
Object o1 = Object(1);
```
根據資料上顯示 Object(1) 是匿名 object 結束後馬上進行 destructor 但是在實驗上反而是直接就轉成有參數的括號法,不知道是不是編譯器太聰明...
* 轉換法
```c++
Object o1 = 10;
Object o1 = o2;
```
調用 copy constructor 將 o2 的內容當作 o1 的初始
### copy constructor 調用
* 用已創建的對象來初始化
```cpp
Object obj1(10);
Object obj2 = obj1;
```
或者
```cpp
Object obj1(10);
Object obj2(obj1);
```
兩種皆屬於用 copy constructor 來初始化新 object
> 以前不知道有第二種 call 法...
>
**注意!以下這種不是 copy constructor**
```cpp
Object obj1(10);
Object obj2;
obj2 = obj1;
```
要記住無論是 copy constructor 還是一般 constructor 都只會調用一次!所以上面的例子是已經調用無參數的 constructor ,後面就是一般的賦值而已
* 把 object 當作參數傳遞
```cpp
void dowork(Object o)
{}
int main()
{
Object o1;
dowork(o1);
}
```
猜測這是因為參數是 object 的 copy ,所以這邊實際上是 `Object o = o1` ,那理所當然最後 dowork() 結束也會 call o 的 destructor
* 把 object 當作回傳值
因為是 local 變數傳出來當作 copy constructor 所以沒關係
```cpp
Object dowork()
{
Object oo(10);
return oo;
}
int main()
{
Object o1 = dowork();
}
```
不過在 local 測試的時候好像會直接 call 有參數的 constructor ,而不是 copy constructor
### 編譯器對於 constructor 的提供機制
* 無任何 constructor
* 提供無參數 constructor
* 提供 copy constructor
* value copy
* 有參數 constructor
* 不提供無參數 constructor
* 強行調用會出錯
* 提供 copy constructor
* value copy
* 有 copy constructor
* 不提供無參數 constructor
* 強行調用會出錯
* 不提供有參數 constructor
* 強行調用會出錯
簡單講層級就是 copy constructor -> 有參數 constructor -> 無參數 constructor
另外 destructor 不管怎樣都會默認提供,**若有指標的話建議自己管理 destructor**
### Shallow copy VS Deep copy
* shallow copy
* 單純的把值複製過去
* 若有 pointer 則兩個 class 的 pointer member 會一樣
* 通常用在只有普通的值的 class
* deep copy
* 重新 allocate 一個空間再把值複製過去
* 有涉及 pointer 之類的使用
常見的錯誤作法:
```cpp
class Object
{
public:
Object(){int *arr = new int[10];}
//...
~Object(){delete arr;}
private:
int *arr;
};
int main()
{
Object o1;
Object o2 = o1;
}
```
o2 離開會先 call destructor , delete 掉 arr ,而 o1 call destructor 也會 delete arr ,兩者因為沒有另寫 copy constructor ,故兩個 arr 會是一樣的,這樣就造成了 double free
### 列表初始化
就是個方便初始化的語法糖而已...
```cpp
class Obj
{
public:
Obj(): a(1), b(2), c(3){};
private:
int a, b, c;
}
```
### class member 為 class
class member 可以是另一個 class 這個沒啥問題,一個比較值得關注的問題是:是 class 先建立還是 member class 先建立?
根據資料和實驗結果是先到 class constructor 但是接著執行 member class constructor 然後才是 class construcotr
順序:
class member constructor -> class constructor
destructor 的部分則是相反
### static class member
* static member variable
* 所有 class 共用變數
* 存放於非 class 內
* 宣告於 class , 初始化於 class 外
* 若初始化於 class 內被當作 const
* static member function
* 所有 class 共用 function
* **static function 僅能 access static variable**
### class model
* this pointer
* this == current object pointer