第12回 解答例
純粋仮想関数とToFの追加
演習の解答例。まず自分で書いてから読むこと。
Sensorを抽象クラスにする
#pragma once
class Sensor {
public:
virtual ~Sensor() = default;
virtual void update() = 0; // 実装を持たない
virtual void print() const = 0;
};= 0を付けるとSensor.cppは不要になる。Sensorは「約束ごと」だけを表す。
直接オブジェクトを作れないことを確認する
Sensor sensor; // コンパイルエラーエラーメッセージの例:
error: cannot declare variable 'sensor' to be of abstract type 'Sensor'
note: because the following virtual functions are pure within 'Sensor':
note: virtual void Sensor::update()「Sensorは抽象型なので変数を作れない。update()が純粋仮想のままだから」と書かれている。エラーメッセージを読む練習になる。
ToFを追加する
#pragma once
#include "Sensor.hpp"
class ToF : public Sensor {
public:
ToF(int pin);
void update() override;
void print() const override;
int getDistanceMm() const;
private:
int pin;
int distanceMm;
};#include <Arduino.h>
#include "ToF.hpp"
ToF::ToF(int pin)
: pin(pin), distanceMm(0) {
}
void ToF::update() {
// 実機では距離センサから読む
distanceMm = analogRead(pin);
}
void ToF::print() const {
Serial.print("ToF distance=");
Serial.println(distanceMm);
}
int ToF::getDistanceMm() const {
return distanceMm;
}継承と抽象クラスの使い分け
| やりたいこと | 使うもの | 例 |
|---|---|---|
| 共通の実装をまとめたい | 普通の継承 | Deviceのピン番号とbegin() |
| 共通の約束ごとを決めたい | 抽象クラス | Sensorは必ずupdate()を持つ |