天天看點

C++用純虛函數實作協定托付的樣例

  C++不像其它非常多程式設計語言有接口、托付或者協定的概念,可是利用純虛函數和C++多重繼承的特性,我們也能實作接口、托付或協定要做的事情,以下的通過一個人設定鬧鐘然後被鬧鐘喚醒的樣例來說明怎樣在C++中實作托付回調。

#include <iostream>
#include <unistd.h>

using std::cout;
using std::endl;

// 用純虛函數設計一個協定
// 實作該協定的類有一個被喚醒的行為
class Awakable {
public:
    // 純虛函數
    virtual void beAwaken() = 0;
};

// 鬧鐘類
class AlarmClock {
public:
    // 托付方(誰托付了鬧鐘提供喚醒服務)
    Awakable *delegate;
    // 在指定時間後報警
    void alarmAfter(int) const;
};

void AlarmClock::alarmAfter(int seconds) const {
    sleep(seconds);
    cout << "叮咚 叮咚 叮咚" << endl;
    // 回調托付方的方法
    delegate->beAwaken();
}

// 人類(實作了Awakable協定能夠被喚醒)
class Person : public Awakable {
public:
    // 啟動鬧鐘并指定喚醒時間
    void rollClock(int);
    // 協定中的被喚醒的行為
    void beAwaken();
};

void Person::rollClock(int seconds) {
    cout << "人設定了鬧鐘" << seconds << "秒後響鈴" << endl;
    // 在棧上建立鬧鐘對象
    AlarmClock ac;
    // 設定托付方
    ac.delegate = this;
    ac.alarmAfter(seconds); 
}

void Person::beAwaken() {
    cout << "人被鬧鐘喚醒了" << endl;
}

int main(void) {
    // 在堆上建立人的對象
    Person *person = new Person;
    // 人啟動鬧鐘設定5秒後被喚醒
    person->rollClock(5);
    // 釋放指針指向的堆空間
    delete person;
    return 0;
}