---
# System prepended metadata

title: C++ 名詞定義

---

### Object 的定義

> n4868(6.7.2) : An object occupies a region of storage in its period of construction ([class.cdtor]), throughout its lifetime, and in its period of destruction ([class.cdtor])

一個 Object 從建構前、使用期間、到解構完，都會占著一個記憶體區塊

### Type 的定義

> n4868(6.8.1) : [basic.types] and the subclauses thereof impose requirements on implementations regarding the representation of types. There are two kinds of types: fundamental types and compound types. Types describe objects, references, or functions.

可見 Type 主要分成兩種，Fundmental 以及 Compound Type，並且 Type 用於描述 object、references 還有 "functions"，有點玄的說法是：型別的目的是描述 object、reference 或 function 的性質和行為

以前比較沒注意到的概念是：函數是有 Type 的，例如說，以下函數是甚麼 Type？

```cpp
int add(int a, int b);
```

答案是 int(int, int)，注意，這個函數的 return type 是 int，但這函數本身的 Type 是 int(int, int)

### Variable 的定義

我們可以給 object 取名字，習慣上我們會稱有名字的 object 為 variable，但 spec 裡面有寫道：

> n4868(6.1) : A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable’s name, if any, denotes the reference or object.

這句話是說：variable 藉由 reference 的宣告或 object 的宣告去引入的，只要是 object 或者是 static data member 的 reference 都可以稱為 variable

### Entity 的定義

entity 是一個抽象的概念，通俗的講就是指該程式編譯過程的零件，因此他是以下這些東西的統稱，而 macro 不是 Entity 就是因為他是 preprocessor 過程在處理的東西，在編譯時就都已經消失

n4868(6.1)：An entity is a value, object, reference, structured binding, function, enumerator, type, class member, bit-field, template, template specialization, namespace, or pack.

### Reference 的定義

註：reference 是能參考到函數的，本質上就是個別名

一但 reference 被初始化，我們就無法再對 reference 本身進行操作了


比較：![](https://hackmd.io/_uploads/HJsiIiiPn.png)

const 物件沒辦法使用 move 去移動到其他物件
物件被移動後，原本的 object 仍然是 valid 的

### C++ 初始化的種類

Value initialization, e.g. std::string s{};
Direct initialization, e.g. std::string s("hello");
Copy initialization, e.g. std::string s = "hello";
List initialization, e.g. std::string s{'a', 'b', 'c'};
Aggregate initialization, e.g. char a[3] = {'a', 'b'};
Reference initialization, e.g. char& c = a[0];


## C++ Object 的定義


一個 Object 有以下特性：

- Size（可以透過 sizeof 確定）
- Align（可以透過 alignof 確定）
- Storage Duration（自動的、靜態的、動態的）
- Lifetime
- Type
- value
- Identifier（Optional）

### Type ID 是甚麼？


### Identifier 的定義

### Variable 的定義撇除了 non-static data member，為甚麼？

https://stackoverflow.com/questions/12987259/why-is-a-non-static-data-member-reference-not-a-variable

### Declare Specifier 的深度理解

![](https://hackmd.io/_uploads/Hyq1XDd_2.png)

註：Type Specifier 和 Type 是不一樣的，立如果 unsigned 可以做為 Type Specifier，但弄出來的 Variable 的 Type 實際上是 Unsigned Int，Auto 是個 Type Speicifier，但不是 Type

範例：
```cpp
```#include <type_traits>
 
struct S
{
    int member;
    // decl-specifier-seq is "int"
    // declarator is "member"
} obj, *pObj(&obj);
// decl-specifier-seq is "struct S { int member; }"
// declarator "obj" declares an object of type S
// declarator "*pObj" declares a pointer to S,
//     and initializer "(&obj)" initializes it
 
int i = 1, *p = nullptr, f(), (*pf)(double);
// decl-specifier-seq is "int"
// declarator "i" declares a variable of type int,
//     and initializer "= 1" initializes it
// declarator "*p" declares a variable of type int*,
//     and initializer "= nullptr" initializes it
// declarator "f()" declares (but doesn't define)
//     a function taking no arguments and returning int
// declarator "(*pf)(double)" declares a pointer to function
//     taking double and returning int
 
int (*(*var1)(double))[3] = nullptr;
// decl-specifier-seq is "int"
// declarator is "(*(*var1)(double))[3]"
// initializer is "= nullptr"
 
// 1. declarator "(*(*var1)(double))[3]" is an array declarator:
//    Type declared is: "(*(*var1)(double))" array of 3 elements
// 2. declarator "(*(*var1)(double))" is a pointer declarator:
//    Type declared is: "(*var1)(double)" pointer to array of 3 elements
// 3. declarator "(*var1)(double)" is a function declarator:
//    Type declared is: "(*var1)" function taking "(double)",
//    returning pointer to array of 3 elements.
// 4. declarator "(*var1)" is a pointer declarator:
//    Type declared is: "var1" pointer to function taking "(double)",
//    returning pointer to array of 3 elements.
// 5. declarator "var1" is an identifier.
// This declaration declares the object var1 of type "pointer to function
// taking double and returning pointer to array of 3 elements of type int"
// The initializer "= nullptr" provides the initial value of this pointer.
 

 
int main()
{
    static_assert(std::is_same_v<decltype(var1), decltype(var2)>);
}
```
### 為甚麼宣告 class 後面需要加上 semicolon


### Resource Acquisition Is Initialization RAII

RAII 的思想是，Resource 的使用一般經歷三個步驟：

- 獲取
- 使用
- 銷毀

但銷毀是常常忘記的一個環節，而 C++ 的語言特性就是為了方便我們去達到這目的而存在的，當我們在 function 中 declare 一個 local variable 的時候，就會自動呼叫 constructor 來進行 object 的初始話，而當 function 執行完了以後，也會自動呼叫 destructor，所以我們只需要把獲取資源的動作寫在 constructor 之中，銷毀的動作寫在 Destructor 之中，C++ 的語法特性就會自動幫我們記得釋放資源，都不需要人工介入

### 三法則、五法則、零法則

假如 class 有明顯自定義下列其中一個 member function，那麼在極大多數情況下，programmer 必須也要自定義另外的兩個，也就是說只要以下三個 member function 其中一個為自定義，那麼下列三個缺一不可

- Copy Constructor
- Copy Assignment Operator
- Destructor

上述三個 member function 是特別的成員函式，假如 programmer 沒有自定義或宣告這三個函式，編譯器仍會自動建立他們，然而如果 programmer 僅定義其中一個，其餘兩個 member function 仍然會由編 compiler 自動產生，這種混雜的情況非常容易產生難以預期的錯誤，三法則的存在，正是提醒 programmer 避免那樣的陷阱

C++11 大改版後，三法則就被擴展成以下五法則，但法則內容仍然相同

- Copy Constructor
- Move Constructor
- Copy Assignment Operator
- Move Assignment Operator
- Destructor

### 為甚麼需要 Reference？

邏輯上來說，一個 reference 是一個已存在的 object 的 alias，並且必須在初始化時指定一個對應的變數。一旦參考被初始化，它就一直指向同一個變數，不能再被重新指定。這意味著參考永遠不會為 null，且不能被指向其他變數。

參數另一個好處。傳遞者不需要知道接受者是以 pass by value or pass by reference 實作 這也解決指標語法上的問題

實作上來說，Reference 可能是用指標實作，也可能不是

### 那麼邏輯上的 Reference 是怎麼樣的？

什麼是參考 (Reference) ?
參考是一種變數，其型別(Type) 是他連結到的東西的型態的引用(reference to type)，這邊不講物件的原因是因為他連結到的東西不一定是個物件，也有可能是函式之類的東西，語法長這樣：

一但 reference 被初始化，我們就無法再對 reference 本身進行操作了。我們也不能有參考的參考(reference to reference)，參考的陣列(arrays of reference)，和參考的指標(pointer to references)，因為 reference 並不是物件(object)。

n4868(9.3.4.3)：There shall be no references to references, no arrays of references, and no pointers to references.

### const 與 constexpr

https://subingwen.cn/cpp/constexpr/

### 解讀 pointer to member access operator

![](https://hackmd.io/_uploads/rk9rPK5dn.png)

### static 在類別中的意義

static 非常容易造成歧異，因為這個 keyword 放在不同地方會有不同作用，"例如說，static 用來修飾一般的 function 和修飾 class 的靜態 member function 功能完全不同，一點點點關係都沒有"

### 為甚麼可以用 . -> 取得靜態成員函數

使用 類別去取得靜態成員會比使用 instance 去取得更好
https://stackoverflow.com/questions/11977137/why-is-calling-a-static-member-function-with-or-syntax-legal
In The Design and Evolution of C++ at page 288, Bjarne Stroustrup mentions that in the days before static member functions, programmers used hacks like ((X*)0)->f() to call member functions that didn't need an object. My guess is that when static member functions were added to the language, access through -> was allowed so that programmers with code like that could change f to static without having to hunt down and change every use of it.


### Auto 的規則

1. ![](https://hackmd.io/_uploads/SkBjzRys2.png)
![](https://hackmd.io/_uploads/ry3oG01jh.png)
![](https://hackmd.io/_uploads/SkN2M0ys2.png)
![](https://hackmd.io/_uploads/ryy6GRys2.png)
![](https://hackmd.io/_uploads/r1el7Akin.png)

### Decltype 的規則

![](https://hackmd.io/_uploads/H1ccSRyin.png)
