iT邦幫忙

2021 iThome 鐵人賽

0
Arm Platforms

STM32 基礎入門教學系列 第 26

【Day26】:從struct進化成class的物件導向技巧(下)

建構子

建構子(constructor)是一種初始化類別物件的成員函式,每一種類別都有一個建構子,當宣告時如果沒有定義建構子,則程式會自動提供一個沒有任何程式敘述及參數的預設建構子(Default Constructor)。
建構子具有以下三個特性,如下:

  1. 建構子的名稱與類別名稱相同,例如類別名稱為Car,則建構子為Car()。
  2. 不須指定回傳型態,因為建構子沒有回傳值。
  3. 建構子可以有多載功能,也就是一個類別內可以存在多個相同名稱,但參數列不同的建構子。

建構子是相當好用的技巧,用於類別的初始化,是個相當好用的技巧

底下就來介紹幾個我實際使用時的情況吧

class Servo {
private:
	TIM_HandleTypeDef *timer;
	int channel;
	int angle;
public:
	Servo(TIM_HandleTypeDef *t, int c);
	void set_angle(double angle);
};

Servo::Servo(TIM_HandleTypeDef *t, int c) {
	timer = t;
	channel = c;
}

大家一看就知道這是一個伺服馬達的類別吧,伺服馬達的控制很簡單,就是輸出PWM。而不同PWM要輸出到不同Timer的不同頻道,因此這一個類別就要有兩個變數,指標變數timer和整數變數channel,而由於這兩個參數不應該被改動,因此我將其設定為private。
而當一宣告Servo這個變數的時候,就要傳入兩個參數,一個是timer的結構變數,另外該PWM輸出是哪一個channel的,而在建構子函數我們就將傳進來的兩個參數儲存到timer與channel變數中。宣告方式如下:

Servo servo1(&htim3, 3);

由於我們只著重在建構子的使用,因此set_angle()這個成員函式我們就不多做介紹了。
我們完全可以不設計建構子,但只要你建立了一個建構子,那程式就不會再幫你產生一個不做任何事的建構子,因此在宣告變數的時候就一定要傳入參數。以上面Servo為例,我們就一定要傳入兩個參數,不可以用以下的方式來宣告

Servo servo1;

多型(Polymorphism)

這也是C++相當好用的一個功能之一。實際上多型的用法相當複雜,我們先只介紹最基本的用法。「多型」的精神在於,可以宣告相同名稱,但不同功能的成員函式。一樣以我實際使用的方式來介紹吧~

class Car {
private:
	double l1, l2;
public:
	double x;
	double y;
	Car();
	void move(double vx, double vy, double w0);
	void move(int dir, double dist);
	void stop();
};

我先說明一下,我想達到兩種移動車子的方式,首先第一種是,給x、y、w0分別代表x分量速度、y分量速度、旋轉角速度,讓車子以這樣的方式移動。第二種移動車子的方式是給予一個方向,並讓車子以這個方向移動一段距離。
我們就可以以同樣的名稱來宣告函式,只是參數列不同,讓整個程式的閱讀又更值觀了。
這裡的重點在於可以以相同的名稱來宣告函數,而如何實作出這兩個函式就不在本篇教學的範圍囉

小結

今天我們又講解了兩個物件導向重要的觀念與小技巧,當然「物件導向」是相當巨大的一個觀念,不太可能靠我們這兩天的介紹就介紹完,我們只介紹幾個寫程式時很實用,也讓程式更好閱讀的方法。


上一篇
【Day25】:從struct進化成class的物件導向技巧(上)
下一篇
【Day27】:STM32實際應用1—馬達精準控速(PID初淺教學(上))
系列文
STM32 基礎入門教學30

尚未有邦友留言

立即登入留言