【C++ 筆記】類別(Class)的基礎概念 - part 17
===
目錄(Table of Contents):
[TOC]
---
很感謝你點進來這篇文章。
你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧!
簡介(Introduction)
---
C++ 是一種物件導向程式設計(**object-oriented programming:OOP**)之語言。
通常有 OOP 的程式語言,都會具有 `Class` 類別,這種概念。
:::success
那麼物件是什麼呢?
物件(Object):具有兩種性質,稱為屬性(Attributes)及方法(Methods)。
1. 屬性(Attributes):
屬性是用來敘述物件特性的資料,通常是物件的狀態,也常被定義為 class 中的「變數」。
例:在名為「car」的物件中,屬性可以為 `顏色`、`品牌`、`速度` 等。
也可以想成是RPG角色的「能力屬性」,`STR`、`HP`、`MP`、`DEX` 等等。
2. 方法(Methods):
簡言之,就是一個物件他的「行為」,Methods 通常是 class 中的 function。
例:在「car」物件中,方法可以是 `加速()`、`剎車()`、`開門()` 等。
:::
而物件導向程式設計共具有以下四項特性:
1. 封裝(Encapsulation)
2. 繼承(Inheritance)
3. 多型(Polymorphism)
4. 抽象(Abstraction)
至於這四種特性有何意義,請待後續章節解釋~本章主要講解 class 基礎應用。
---
### class 與 物件的關係
class 為物件的藍圖或模板,由於在仍在藍圖上組織、架構物件的屬性跟方法,所以此時真正的物件是還沒有被「實現」出來的!
:::warning
class 就像在RPG遊戲中創建角色,還在捏臉、取名字一樣。
:::
而物件則被稱為 class 的實例(instance),是一個已經從藍圖中實現出來、具體、具象化的東西、一個物件。
:::warning
例如我們想要打造出一台車,務必是要在藍圖上設計車子(此為設計 class 的過程),等設計完後,會送入各個工廠生產零件,最後再進行組裝,得出一個具體的物件(Object),即為 class 的實例。
:::
C++ class 定義(Create a class)
---
若要在 C++ 中定義類別,則需要使用關鍵字 `class`,如下圖:

Image Source:https://www.geeksforgeeks.org/c-classes-and-objects/
`class` 關鍵字輸入完後,再加一個空格,填入類別名稱,其後加上兩個大括號 `{}`。
`Access specifier`:存取修飾詞。在 C++ 為 `private`、`public`、`protected`。至於這三者有何功用,後續小節解釋。
`Data members`:資料成員。是在 class 當中被使用的變數。
`Member Function() {}`:成員函數。前面說過,在 class 裡面的函數就稱為方法(Methods),而他可以存取資料成員。
:::danger
最後要記得在右大括號加上一個分號,以示結束。
:::
以下是一個簡短的程式,表示在 C++ 中建立一個 class:
```cpp=
class ThisClass {
public:
int var; // data member
void print() { // member method
cout << "Hello";
}
};
```
Source:https://www.geeksforgeeks.org/c-classes-and-objects/
定義物件(Create an Object)
---
如同宣告變數一般,只是宣告時要將 data type 的部分改成 class 名稱,後面再為物件取名,如下:
```cpp=
ThisClass myclass1;
ThisClass myclass2;
```
可看到上面有 myclass1、myclass2 兩種物件(想像成已經從藍圖中跳脫出來的實體物件)。
存取資料成員(Access a data member)
---
存取資料成員,也可稱為存取物件的屬性,要存取時使用成員存取運算子 `.`,一個小點即可。
具體而言,可視為此格式:`物件名稱.類別裡面定義的屬性`
請看以下例子:
```cpp=
#include <iostream>
#include <string>
using namespace std;
// 定義一個類別名為 'Person'
// Define a class named 'Person'
class Person {
public:
// 資料成員
// Data members
string name;
int age;
// 用成員函數去介紹人
// Member function to introduce the person
void introduce()
{
cout << "Hi, my name is " << name << " and I am "
<< age << " years old." << endl;
}
};
int main()
{
// 建立一個 Person 類別的物件
// Create an object of the Person class
Person person1;
// 存取資料成員
// accessing data members
person1.name = "Alice";
person1.age = 30;
// 呼叫 introduce() 成員方法
// Call the introduce member method
person1.introduce();
return 0;
}
```
輸出結果:
```
Hi, my name is Alice and I am 30 years old.
```
Source:https://www.geeksforgeeks.org/c-classes-and-objects/
存取修飾詞(Access Modifiers)
---
在 C++ 中共有 3 種存取修飾詞,其中最常見的為 public:
* `public`:宣告為 public 的成員可以從 class 外部存取。
* `private`:宣告為 private 的成員只能在 class 內部存取。
* `protected`:宣告為 protected 的成員可以在 class 內部和衍生類別(derived classes)中存取。
private、protected 兩者間僅 protected 可以在衍生類別中存取,而其餘能在 class 內部存取的特性是相同的。
:::info
若不特別指明存取修飾詞,則預設會使用 private。
:::
以下是一個範例,有關於 public 與 private 兩者的展示:
```cpp=
#include <iostream>
using namespace std;
class Base {
public:
// public 成員, 可於 class 外部直接存取
void publicMethod() {
cout << "This is a public method." << endl;
}
private:
// private 成員, 僅於 class 內部存取
void privateMethod() {
cout << "This is a private method." << endl;
}
public:
// 公開一個函數存取 private 成員
void accessPrivateMethod() {
privateMethod();
}
};
int main() {
Base baseObj;
// 測試 public 成員
baseObj.publicMethod(); // 可直接存取
// 測試 private 成員
// baseObj.privateMethod(); // 無法直接存取, 會導致編譯錯誤
baseObj.accessPrivateMethod(); // 透過 public 方法間接存取
return 0;
}
```
輸出結果:
```
This is a public method.
This is a private method.
```
成員函數(Member Function)
---
成員函數其實就是方法(Method),簡言之,成員函數可以看成是 C++ 版本的方法,而 Method 這個詞在 OOP 中是一個泛稱,所以就醬。
根據 GeeksforGeeks,列出了以下兩點定義成員函數的方式:
* 內部類別定義(Inside class definition)
* 外部類別定義(Outside class definition)
成員函數若在 class 內部定義時,就跟一般函數定義形式相同;若在 class 外部定義時,需要使用範圍解析運算子 `::` 兩個半型冒號。
具體該如何使用,先看內部定義時的範例:
```cpp=
class Box
{
public:
double length; // 長度
double breadth; // 寬度
double height; // 高度
double getVolume(void)
{
return length * breadth * height;
}
};
```
再來是外部定義時,使用 `::` 的情形:
```cpp=
double Box::getVolume(void)
{
return length * breadth * height;
}
```
來源:https://www.runoob.com/cplusplus/cpp-class-member-functions.html
:::success
必須注意的是,若要使用此外部定義形式,在範圍解析運算子的前面記得要加上 class 名稱。
:::
若要呼叫成員函數,則與存取資料成員一樣,使用 `.`,"點"前面接物件名,後面接成員函數,如下:
```cpp=
myclass abc;
abc.this_is_function();
```
總結
---
礙於內容篇幅,故於此作結。
C++ 是一種支援物件導向程式設計(OOP)的語言。物件由屬性(Attributes)與方法(Methods)構成:
* **屬性**是物件特性的資料,為類別中的變數。
* **方法**是物件的行為,為類別中的函數。
**OOP 的四大特性:**
* **封裝(Encapsulation)**
* **繼承(Inheritance)**
* **多型(Polymorphism)**
* **抽象(Abstraction)**
**類別與物件的關係:**
* **類別(Class)**:物件的藍圖(設計圖),用於設計屬性與方法。
* **物件(Object)**:類別的實例,具現化的物件。
**在 C++ 中使用類別與物件:**
1. **定義類別**:
使用 `class` 關鍵字定義類別,如下:
```cpp=
class ThisClass {
public:
int var; // 資料成員
void print() { cout << "Hello"; } // 成員函數
};
```
2. **建立物件**:
```cpp=
ThisClass myclass1;
ThisClass myclass2;
```
3. **存取資料成員與方法**:
用 `.`(成員存取運算子)存取物件的屬性或方法:
```cpp=
myclass1.var = 10;
myclass1.print();
```
**存取修飾詞**:
C++ 提供 3 種存取修飾詞:
* **public**:可在類別外存取。
* **private**:僅限類別內存取(預設用此修飾詞)。
* **protected**:僅類別內與衍生類別可存取。
**成員函數的定義方式**:
1. **內部定義**:直接在類別內定義方法:
```cpp=
double getVolume() { return length * breadth * height; }
```
2. **外部定義**:使用範圍解析運算子 `::`:
```cpp=
double Box::getVolume() { return length * breadth * height; }
```
參考資料
---
[範圍解析運算子:`::` | Microsoft Learn](https://learn.microsoft.com/zh-tw/cpp/cpp/scope-resolution-operator?view=msvc-170)
[C++ Class Methods](https://www.w3schools.com/cpp/cpp_class_methods.asp)
[C++ Access Specifiers](https://www.w3schools.com/cpp/cpp_access_specifiers.asp)
[C++ Classes and Objects - W3Schools](https://www.w3schools.com/cpp/cpp_classes.asp)
[C++ Classes and Objects - GeeksforGeeks](https://www.geeksforgeeks.org/c-classes-and-objects/)
[OOP 物件導向的四個特性](https://coreychen71.github.io/posts/2019-10/oop/)
[成員存取運算子:'.' 和 '->' | Microsoft Learn](https://learn.microsoft.com/zh-tw/cpp/cpp/member-access-operators-dot-and?view=msvc-170)
[C++ 类成员函数 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-class-member-functions.html)
[C++ 类访问修饰符 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-class-access-modifiers.html)
[C++ 类 & 对象 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-classes-objects.html)