# C++ structure and class
---
#### What is struct/class
* What: Encapsulate multiple data to one.
* Why: Give the structure a meaning.
* How:
``` cpp
struct People {
std::string name;
int age;
int height;
int weight
};
```
---
#### The expression of the struct/class
* Keyword: `struct/class`
* Member `variables/functions`
* Access specifiers: `public/private/protected`
* 表示外部的code是否可以訪問這個作用域
* 如果表示為private的函式跟變數,除了自己以外不能使用
* 如果表示為public的函式或變數則為公開變數,可以供人使用
* Remember add the semicolon at the end.
---
#### The expression of the struct/class
``` cpp
// use class to define
class People {
// Access specifiers
public:
// member functions
std::string getName() {return name;}
std::string getAge() {return age;}
void setName(std::string n){name=n;}
void setAge(int a){age=a;}
void introduceMySelf() {
std::cout<<"My name is "<<getName()
<<", and age is "<<getAge()<<"\n";
}
private:
// member variables
std::string name;
int age;
}; // <-- Add the semicolon
```
---
### Example
``` cpp
int main() {
std::string name;
int age;
std::cin>>name>>age;
People Ann;
// Ann.name = name, compile error because name is a private member
// Ann.age = age, compile error because age is a private member
Ann.setName(name);
Ann.setAge(age);
Ann.introduceMySelf();
// My name is Ann, and age is 18
}
```
---
#### What is difference between class and struct.
* In C language, there is only struct and no member functions in it.
* In C++ language, only one difference.
* The default access specifier is private for class and public for struct.
---
#### LifeTime and Initialization
* 所有的變數都有它的生命週期
* 全域變數會存活在整個程式中,生命週期無限大
* 區域變數會存活在某一個區間
* 兩個括號之間{}
* 或者一個function之間
---
#### LifeTime and Initialization
* 區域變數會存活在某一個區間
* 兩個括號之間{}
* 或者一個function之間
``` cpp
int main() {
int a = 0; // 在宣告時創造,在離開main時結束
if (a==0) {
People Ann; // 在進入if後創造它,並在離開if時結束
Ann.setAge(18);
std::cout<<Ann.getName()<<"\n";
// ↑--------------↑---
// getName回傳的std::string只存在於<<之間
}
{
People Ann; // 在進入這個{}後創造它,並在離開{}時結束
}
}
```
---
#### LifeTime and Initialization
* 所有的變數都有它的生命週期
* 全域變數會存活在整個程式中,生命週期無限大
* 區域變數會存活在某一個區間
* 兩個括號之間{}
* 或者一個function之間
* 任何變數在使用前都要先思考要怎麼初始化,以及怎麼解構
* class has constructor/desturctor
---
#### LifeTime and Initialization

---
#### Initialization
* 有兩種初始化的寫法
* 第一種直接在宣告member variable的時候給定初始值
* Constructor
```cpp=
class People {
int age=0;
std::string name="";
}
```
---
#### Initialization
* Constructor
* 於class中特殊的寫法,使用跟class相同名稱當作開頭
* 從: 到 {} 中間為initialize list(初始化列表),以','分隔
* 初始化列表內的順序要跟member一致
* {}內可想像成function body,做一些初始化會做的事情
```cpp=
class People {
public:
People():age{0}, name{""}{}
private:
int age;
std::string name;
}
```
---
#### Initialization
* Constructor 可接受多個變數
``` cpp=
class People {
public:
People(std::string n, int a):age{a}, name{n}{}
private:
int age;
std::string name;
}
int main() {
People Ann{"Ann", 18};
return 0;
}
```
---
#### specifal constructor and destructor
* default constructor
* copy constructor
* copy assignment
* move constructor
* move assignment
* destructor
---
#### specifal constructor and destructor
```cpp=
int main() {
People Ann; // Default constructor
People Ann2 = Ann; // Copy constructor
People Ann3; // Default constructor
Ann3 = Ann; // Copy Assignment;
Poeple Ann4 = std::move(Ann3) // move constructor
Ann3 = std::move(Ann); // move assignment;
} // Call destructor of Ann/Ann2/Ann3/Ann4 before leave main
```
---
#### specifal constructor and destructor
``` cpp=
class People {
public:
// Default constructor
People():age{0}{}
// Copy constructor, use const People& in the parameters.
People(const People& p):age{p.age}{}
// Move constructor, like copy but use People&&
People(People&& p):age{p.age}{}
// Copy Assignment, redefine the = for People
// Return type must be People&
// Return *this at the end.
People& operator=(const People& p){age=p.age; return *this;}
// Move Assignment, like copy assignment but parameter use People&&
People& operator=(People&& p){age=p.age; return *this;}
// Destructor
~People(){}
private:
int age;
}
```
---
#### Example
* [Link](https://godbolt.org/z/1PPPPbE97)
``` cpp=
class People {
public:
People():name{"Default"}{std::cout<<"I'm born!\n";}
~People(){std::cout<<"I'm "<<name<<", and I leave!\n";}
void setName(std::string n){name=n;}
private:
std::string name;
};
```
```cpp=
int main() {
People Ann;
Ann.setName("Ann");
{
People Terry;
Terry.setName("Terry");
}
}
```
---
#### Example 2
* 請問這邊會印出甚麼東西來. [Link](https://godbolt.org/z/dYnEbKzvv)
``` cpp=
class People {
public:
People() {std::cout<<"Ctor\n";}
People(const People& p) {std::cout<<"Copy Ctor\n";}
People(People&& p) {std::cout<<"Move Ctor\n";}
People& operator=(const People& p) {std::cout<<"Copy Ass\n"; return *this;}
People& operator=(People&& p) {std::cout<<"Move Ass\n"; return *this;}
~People() {std::cout<<"Dtor\n";}
};
int main() {
People p1;
People p2 = p1;
People p3 = std::move(p2);
p3 = p1;
p3 = std::move(p1);
}
```
---
#### Constructor and Destructor
* 為什麼需要這麼複雜的constructor跟destructor呢
* 在未來會學到pointer,或者你用到別人設計的class時會用到
* pointer需要更為複雜的初始化跟解構
* 別人了class可能需要複雜的初始化以及解構
* Rule of 5 or Rule of 0
* 意思就是說,要馬全部的constructor都寫出來。要馬都不寫。
* 現階段妳可以先不寫這些東西
---
#### You can define everything outside the class
* Why: 你的class應當簡潔有力,把定義包含其中會顯得混亂
* How: 在定義時加入 \<ClassType>::
```cpp=
class People {
public:
People();
People(int a);
~People();
int getAge();
void setAge(int a);
private:
int age;
};
int main(){
//...
}
People::People():age{0} {}
People::People(int a):age{a}{}
People::~People(){}
int People::getAge(){return age;}
void People::setAge(int a){age=a;}
```
---
#### Exercise
* 設計一個簡單的點餐系統。
1. 請輸入Steak, Fish, Chicken, IceCream, Cake的價格
2. 輸入預定人名以及想要預定的時間
3. 輸入想要吃的主餐是甚麼(Steak, Fish, Chicken, None擇一)
4. 輸入想吃的甜點是甚麼(IceCream, Cake, None擇一
5. 輸入是否有會員(Yes/No, 有會員的話打九折)
6. 輸出人名,時間,主餐,甜點,是否有折價,總價格
---
#### Exercise
* [Link](https://godbolt.org/z/K3qrr1E4b)
* 輸入如下
* 
* 輸出如下
* 
* [ANS](https://godbolt.org/z/x981v9sE3)
{"title":"C++ structure and class","slideOptions":"{\"theme\":\"white\"}","contributors":"[{\"id\":\"09379b25-db04-47a4-8912-78e722b7a548\",\"add\":8808,\"del\":1526}]"}