零零碎碎 — 回调函数与多态

回调函数

前天写的视频播放器,第一次在编程中使用了回调函数的接口。当然,这里所说的“函数”是广义的“可调用表达式”,设计签名的时候模仿了OpenCV滚动条,最后一个参数接受void指针传入用户数据。虽然不知道他们这么设计是出于什么考虑(或者是为了兼容c代码?),不过显然在C++中有更好的方案。因为对C++的了解有限,我所能想到的比较好的设计也就是下面这两种:

  • 使用 boost::any 接受用户数据
  • 不接受用户数据,让用户自行绑定

boost::any 可以说就是C++版本的 void *,不过它是类型安全的。至于究竟选择上面的哪一种还是值得好好考虑一番的。首先考虑的就是,是否需要在结构中保存用户数据(值或引用),如果能够保存用户数据的话,则需要一个方法能够从外部修改它。如果是采用第二种方案的话,即使当方法不变而数据需要修改时,都需要向结构重新传入一个绑定的对象。

随后翻了一下Boost手册,倒是找到一个解决方案:使用 boost::ref 绑定对象的引用。这样的话,除非第一种方案改为使用 smart_ptr,否则还真的没什么优势。

多态

经过今天一天的实验发现,boost::any 用来做接口还可以,如果用来构建容器什么的就有点难搞,假设我要设计一个储存任何类型的容器,但容器中的部分类型有共同的几个方法,为了实现这些方法,必须在每个方法中进行类型判定。后来想到可以保存每个元素的type_info,结果发现type_info竟然是不可复制的。

唉,虽说是any类型,但真正一个容器内的元素应当都是为某个目的服务的嘛,像这种具有不同元素类型间具有共同接口的情况,还是用类继承要方便得多。

情况就是这样,现在打算用OO的方式封装OpenCV的 GUI 部分,在一个窗口类中,想设计一个成员变量保存所有窗口组件的信息。一开始本来打算用 boost:any 的方式的,结果发现要操作里面的元素实在是太麻烦了,最后选择使用类继承的方式组织所有窗口组件。学C++断断续续也快两年了,这还是第一次使用继承的特性。果不其然,对于写抽象类是非常的手生,发现要正确写好一个抽象类还有那么多条条框框,所以特地在这里写一遍虚拟类的 checklist ,以加深印象:

  1. 虚拟成员函数前缀 virtual, 纯虚函数后面加 "= 0“;
  2. 抽象类析构函数必须是virtual;
  3. 所有派生类务必定义析构函数(切记!),如果在连接时报错 "undefined reference 'vtable ...'“ 什么的,多半就是忘记定义派生类的析构函数了。

原文链接: https://www.cnblogs.com/liuyangnuts/archive/2013/03/05/2944398.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    零零碎碎 -- 回调函数与多态

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/79763

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午7:12
下一篇 2023年2月9日 下午7:12

相关推荐