---
# System prepended metadata

title: Class
tags: [C++Book]

---

# Class
###### tags: `C++Book`

* 在Class內部實作函數：
    * compiler 會自動當做inline考慮
* 在Class內只宣告函數主體
    * compiler 當做一般函式

## Constructor
沒有定義建構子，編譯器自動假設它有以下 constructor 成員函數：
* Empty constructor
* Copy constructor：它是一個只有一個參數的建構子，該參數是這個 class 的一個物件，這個函數的功能是將被傳入的物件（object）的所有非靜態（non-static）成員變數的值都複製給自身這個 object。

## Create Instance
```cpp=
CRectangle a, *b, *c;
CRectangle * d = new CRectangle[2];
b= new CRectangle;
c= &a;
CRectangle foo (3,4); //constructor
```
## Pointer
* x.y 讀作: member y of object x （對象 x 的成員 y）
* (*x).y 讀作: member y of object pointed by x（由 x 指向的對象的成員 y）
* x->y 讀作: member y of object pointed by x (同上一個等價)
* x[0] 讀作: first object pointed by x（由 x 指向的第一個對象）
* this 指向自己的指標

## static
```cpp    
class CDummy {
public:
static int n;
CDummy () { n++; };
~CDummy () { n--; };
};

int CDummy::n=0;  //static 成員只能在全域範圍初始化
```

## Friend
允許特定成員訪問私有成員
### friend func
允許外部函數訪問private 及 protected 函數
必需在class 內部用關鍵字 friend 來宣告該外部函數的原型，以指定允許該函數共用 class
的成員。
![](https://i.imgur.com/tAKA9pl.png)



### friend class
![](https://i.imgur.com/WMY2GKW.png)


在上面程式的第一句就是 class CSquare 的原型，這是必需的，因為在 CRectangle 的宣告中我們引用了 CSquare (作為 convert()的參數)，而Csquare的定義在後面。
## inherit
### 保護層級
`class CRectangle: public CPolygon;`
這裡關鍵字 public 表示子類別(CRectangle)從父類別(CPolygon)繼承的成員所必
頇獲得最低程度保護程度。這種被繼承成員最低程度的訪問限制可以透過使用
protected 或 private 而不是 public 來改變。例如，daughter 是 mother 的一個子
類別，我們可以這樣定義：
`class daughter: protected mother;`
protected 將使得 daughter 從 mother 處繼承的成員其最低訪問限制為 protected。
也就是說，原來mother 中的所有public 成員到daughter 中將會成為protected 成
員。這最低存取權限限制只是建立在從 mother 中所繼承來的成員上的，並不代
表 daughter 不能有它自己的 public 成員。
如果沒有明確寫出訪問限制，所有由關鍵字 class 衍生的類別被默認為 private ， 而所有由關鍵字 struct 衍生的類別被默認為 public。
### Constructor
如果父類別沒有預設建構子，或你希望當子類別生成新的 object 時，父類別的某 個重載的建構子被調用，你需要在子類別的每一個建構子的定義中指定它
derived_class_name (int arg) : base_class_name (arg) {}
子類接受到的參數會傳給父類的建構子，父類的建構子位置也可是class內的其他建構子多載

### Multiple Inherit 
`class CRectangle: public CPolygon, public COutput {}`

### Virtual Members
![](https://i.imgur.com/0Jt7Y3r.png)
 
### Abastrac Class
![](https://i.imgur.com/SFRyDt3.png)

在virtual 函式上定義=0成為抽象函式，而此 class 成為抽象類別。
抽象父類別的最大不同是它不能夠有實例(物件)，但我們可以定義指向它的指標。
因此，像這樣的宣告：
`CPolygon poly;`
對於前面定義的抽象父類別是不合法的。
然而，指標：
`CPolygon * ppoly1;`
這是因為該類別包含的純虛擬函數(pure virtual function) 是沒有被實現的，所以
這是完全合法的。
			
