C++ 入門指南

單元 12 - 建構函數

函數 (function) 可以有多個參數 (parameter) 版本,建構函數 (constructor) 亦同,具有多個參數版本的函數被稱為多載函數 (overloaded function)

建構函數 ⇉ 多載函數

為什麼會需要多載函數呢?這是因為多載函數可以處理不同型態的參數,例如我們需要一個將數字相加的函數

int a = add(12, 32);

兩個參數 1232 都是整數,運用之前 Demo::do_something() 的實作即可完成,那假如參數有一個不是整數呢?

double b = add(2.53, 32);

由於 C++ 是強型態 (strong typing) 的程式語言,浮點數double整數 int 是不同的資料型態 (data type) ,計算兩種資料型態前要先做型態轉換,不然就有可能會出現無法預期的結果

double add(double p_a, int p_b) {
    double c = (double) p_b;
    return p_a + c;
}

雖然編譯器會自動替基本內建型態 (primitive built-in type) 進行型態轉換,有些地方並不會出錯,可是有些地方就會出錯,保險一點就是我們養成型態轉換的習慣,只要型態不同,就自己加進轉換的程式碼。

多載函數的版本是依參數列中參數的數量與型態,函數只能有一個回傳值,若只有回傳值型態不同,這並不構成另一個多載函數

建構函數的主要目的是設定資料成員 (data member) ,由於 Demo 有兩個資料成員 ab ,因此我們打算設置三種參數版本,分別是沒有參數、一個參數及兩個參數

Demo();
Demo(int);
Demo(int, int);

沒有參數的建構函數直接呼叫修改函數ab 都設定為整數 1 ,一個參數的建構函數ab 都設定為參數值,至於兩個參數的建構函數a 設定為第一個參數, b 設定為第二個參數,實作如下

// 沒有參數的建構函數
Demo::Demo() {
    set_a(1);
    set_b(1);
}

// 一個參數的建構函數
Demo::Demo(int n1) {
    set_a(n1);
    set_b(n1);
}

// 兩個參數的建構函數
Demo::Demo(int n1, int n2) {
    set_a(n1);
    set_a(n1);
    set_b(n2);
}

寫成完整範例如下

#include <iostream>

using namespace std;

class Demo {
// 宣告 public 的成員
public:
    Demo();
    Demo(int n1);
    Demo(int n1, int n2);
    void set_a(int n);
    void set_b(int n);
    int get_a();
    int get_b();
    int do_something();
    
// 宣告 private 的成員
private:
    int a;
    int b;
};

// 沒有參數的建構函數
Demo::Demo() {
    set_a(1);
    set_b(1);
}

// 一個參數的建構函數
Demo::Demo(int n1) {
    set_a(n1);
    set_b(n1);
}

// 兩個參數的建構函數
Demo::Demo(int n1, int n2) {
    set_a(n1);
    set_a(n1);
    set_b(n2);
}

int Demo::do_something() {
    // 改成呼叫 getter 成員函數
    return get_a() + get_b();
}

// setter 與 getter 成員函數
void Demo::set_a(int n) {
    a = n;
}

void Demo::set_b(int n) {
    b = n;
}

int Demo::get_a() {
    return a;
}

int Demo::get_b() {
    return b;
}

int main(void) {
    Demo t1;
    Demo t2(11);
    Demo t3(11, 22);
    
    cout << endl;
    cout << t1.do_something() << endl;
    cout << t2.do_something() << endl;
    cout << t3.do_something() << endl;
    cout << endl;
    
    return 0;
}

/* 《程式語言教學誌》的範例程式
   https://kaiching.org/
   檔名:class_demo3.cpp
   功能:示範定義類別
   作者:張凱慶 */

利用建構函數建立物件 (object) ,宣告變數 (variable) 時加小括弧即可,需要留意沒有參數的建構函數不需要加小括弧

Demo t1;
Demo t2(11);
Demo t3(11, 22);

編譯執行結果如下

-classdemo3-

我們連續介紹了物件導向程式設計中的封裝建構函數,接下來還有個寫 C++ 程式基本並且重要的主題,也就是設計專屬的標頭檔,下面我們繼續討論囉!

中英文術語對照
函數 function
參數 parameter
建構函數 constructor
多載函數 overloaded function
強型態 strong typing
資料型態 data type
基本內建型態 primitive built-in type
資料成員 data member
物件 object
變數 variable
重點整理
1. 具有多個參數版本的函數被稱為多載函數,也就是允許函數有不同的參數列。
2. C++ 是強型態的程式語言,運算式中若有兩種不同的資料型態,就需要先進行型態轉換。
3. 編譯器會替基本內建型態進行自動型態轉換。
4. 函數只能有一個回傳值,若只有回傳值型態不同,這並不構成另一個多載函數。
5. 建構函數的主要目的是設定變數成員。
問題與討論
1. 為什麼兩個函數只有回傳值型態的不同,並不構成多載函數?
2. 為什麼編譯器要替基本內建型態進行自動型態轉換?
3. 建構函數的用途為何?除了設定變數成員外,建構函數還有其他功能嗎?
練習
1. 寫一個程式 exercise1201.cpp ,利用 exercise1101.cpp 設計的 IntegerDemo ,加入建構函數。
2. 寫一個程式 exercise1202.cpp ,利用 exercise1102.cpp 計算階層值的類別,加入建構函數。
3. 寫一個程式 exercise1203.cpp ,利用 exercise1103.cpp 計算費氏數列的類別,加入建構函數。

上一頁 單元 11 - 物件導向與封裝
回 C++ 入門指南首頁
下一頁 單元 13 - 設計專屬的標頭檔
回 C++ 教材
回程式語言教材首頁