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;
}
程序写到这里,我相信已经不用很多其它的言语来解释怎样实现协议托付了。事实上各种编程语言的表象千变万化可是实质差点儿没有差别。相似的功能在Java中用接口(interface)能够做到,在C#中能够使用托付(delegate),在Objective-C中能够使用协议(protocol)。Swift中也有协议这个概念。可是假设你能够理解函数式编程的理念。还有更简单有效的方式就是使用Lambda函数,将一个回调函数直接作为參数传入一个函数或方法中。而Java(Java 8)和C#中都提供了Lambda表达式,OC中也有block来实现同样的功能。那么C++呢。别忘了C++中还有仿函数(函数对象)的概念,这些不都是一致的吗?当然,支持函数式编程范式的语言就更不用说了,就像JavaScript中能够把函数传入函数中,Swift不也是如此吗?