【C++ 筆記】類別(Class)的基礎概念 - part 17

很感謝你點進來這篇文章。

你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧!

簡介(Introduction)

C++ 是一種物件導向程式設計(object-oriented programming:OOP)之語言。

通常有 OOP 的程式語言,都會具有 Class 類別,這種概念。

:::success
那麼物件是什麼呢?

物件(Object):具有兩種性質,稱為屬性(Attributes)及方法(Methods)。

  1. 屬性(Attributes):
    屬性是用來敘述物件特性的資料,通常是物件的狀態,也常被定義為 class 中的「變數」。
    例:在名為「car」的物件中,屬性可以為 顏色品牌速度 等。
    也可以想成是RPG角色的「能力屬性」,STRHPMPDEX 等等。
  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

Image Source:https://www.geeksforgeeks.org/c-classes-and-objects/

class 關鍵字輸入完後,再加一個空格,填入類別名稱,其後加上兩個大括號 {}

Access specifier:存取修飾詞。在 C++ 為 privatepublicprotected。至於這三者有何功用,後續小節解釋。

Data members:資料成員。是在 class 當中被使用的變數。

Member Function() {}:成員函數。前面說過,在 class 裡面的函數就稱為方法(Methods),而他可以存取資料成員。

:::danger
最後要記得在右大括號加上一個分號,以示結束。
:::

以下是一個簡短的程式,表示在 C++ 中建立一個 class:

1
2
3
4
5
6
7
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 名稱,後面再為物件取名,如下:

1
2
ThisClass myclass1;
ThisClass myclass2;

可看到上面有 myclass1、myclass2 兩種物件(想像成已經從藍圖中跳脫出來的實體物件)。

存取資料成員(Access a data member)

存取資料成員,也可稱為存取物件的屬性,要存取時使用成員存取運算子 .,一個小點即可。

具體而言,可視為此格式:物件名稱.類別裡面定義的屬性

請看以下例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#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;
}

輸出結果:

1
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 兩者的展示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#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;
}

輸出結果:

1
2
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 外部定義時,需要使用範圍解析運算子 :: 兩個半型冒號。

具體該如何使用,先看內部定義時的範例:

1
2
3
4
5
6
7
8
9
10
11
12
class Box
{
public:
double length; // 長度
double breadth; // 寬度
double height; // 高度

double getVolume(void)
{
return length * breadth * height;
}
};

再來是外部定義時,使用 :: 的情形:

1
2
3
4
double Box::getVolume(void)
{
return length * breadth * height;
}

來源:https://www.runoob.com/cplusplus/cpp-class-member-functions.html

:::success
必須注意的是,若要使用此外部定義形式,在範圍解析運算子的前面記得要加上 class 名稱。
:::

若要呼叫成員函數,則與存取資料成員一樣,使用 .,”點”前面接物件名,後面接成員函數,如下:

1
2
myclass abc;
abc.this_is_function();

總結

礙於內容篇幅,故於此作結。

C++ 是一種支援物件導向程式設計(OOP)的語言。物件由屬性(Attributes)與方法(Methods)構成:

  • 屬性是物件特性的資料,為類別中的變數。
  • 方法是物件的行為,為類別中的函數。

OOP 的四大特性:

  • 封裝(Encapsulation)
  • 繼承(Inheritance)
  • 多型(Polymorphism)
  • 抽象(Abstraction)

類別與物件的關係:

  • 類別(Class):物件的藍圖(設計圖),用於設計屬性與方法。
  • 物件(Object):類別的實例,具現化的物件。

在 C++ 中使用類別與物件:

  1. 定義類別
    使用 class 關鍵字定義類別,如下:
    1
    2
    3
    4
    5
    class ThisClass {
    public:
    int var; // 資料成員
    void print() { cout << "Hello"; } // 成員函數
    };
  2. 建立物件
    1
    2
    ThisClass myclass1;
    ThisClass myclass2;
  3. 存取資料成員與方法
    .(成員存取運算子)存取物件的屬性或方法:
    1
    2
    myclass1.var = 10;
    myclass1.print();

存取修飾詞

C++ 提供 3 種存取修飾詞:

  • public:可在類別外存取。
  • private:僅限類別內存取(預設用此修飾詞)。
  • protected:僅類別內與衍生類別可存取。

成員函數的定義方式

  1. 內部定義:直接在類別內定義方法:
    1
    double getVolume() { return length * breadth * height; }
  2. 外部定義:使用範圍解析運算子 ::
    1
    double Box::getVolume() { return length * breadth * height; }

參考資料

範圍解析運算子::: | Microsoft Learn

C++ Class Methods

C++ Access Specifiers

C++ Classes and Objects - W3Schools

C++ Classes and Objects - GeeksforGeeks

OOP 物件導向的四個特性

成員存取運算子:’.’ 和 ‘->’ | Microsoft Learn

C++ 类成员函数 | 菜鸟教程

C++ 类访问修饰符 | 菜鸟教程

C++ 类 & 对象 | 菜鸟教程