更健壮的 C++ 对象生命期管理
以下的这个 C++ 技巧是前段时间一个同事介绍给我的,而他是从 fmod 中看来。当时听过后没怎么在意,主要是因为这两年对 C++ 的奇技淫巧兴趣不大了。今天跟另一同事讨论一些设计问题时,突然觉得似乎在某些地方还有点用途,就向人介绍了一番。讲完了后觉得其实还是有点意思,不妨写在 blog 上。
问题的由来是这样的:音频播放的模块中比较难处理的一个问题是,波形(wave sample)数据对象的生命期管理问题。因为你拿到一个对象后,很可能只对它做一个播放(play)的操作,然后就不会再理会它了。但是这个对象又不能立刻被释放掉。因为声卡还在处理这些数据呢。我们往往希望在声音停止后,自动销毁掉这个对象。
另一些时候,我们还需要对正在播放的声音做更细致的控制。尤其在实现 3d 音效,或是做类似多普勒效应的声音效果的时候。
C++ 中传统的方法是用智能指针的方式来管理声音对象,但这依赖语言本身的一些特性。fmod 提供了诸多语言的接口,它在为 C++ 提供接口的时候利用了一个更为巧妙的方法。
声音的类工厂并不需要生产出一个真正的对象指针,而是返回一个唯一 ID 。但是在语法层面上看,它却是一个对象指针。也就是说,如果你用调试器去看这个指针的值,他很有可能是 1,2,3,4 这样的数字。
如果这个类不提供任何虚方法,也没有直接可以访问的成员变量的话,对这个指针做任何成员函数调用其实都是合法的。因为 C++ 的普通成员函数调用仅仅只是把对象指针做为一个特殊的叫做 this 的参数传入函数而已。比如这样的代码是完全可以正常运行的:
那么库的实现只需要在每个成员函数的开始,利用一张 hash 表,把 this 表示的 id 转换成内部真正的对象指针即可。如果这个 id 对应的对象已经被销毁,则可以安全的退出函数调用。
这个技巧提高了库的健壮性,其代价是每次成员函数调用都需要多一次 hash 表查询操作。如果想优化一下性能的话,不妨 cache 住最近访问过的对象。
Comments
Posted by: dee | (41) February 18, 2008 10:18 AM
Posted by: GGG | (40) January 21, 2008 03:46 PM
Posted by: Albert | (39) July 20, 2007 05:24 PM
Posted by: Anonymous | (38) July 10, 2007 10:41 PM
Posted by: missdeer | (37) July 8, 2007 10:21 AM
Posted by: mike | (36) July 7, 2007 06:24 PM
Posted by: Cloud | (35) July 6, 2007 12:56 AM
Posted by: analyst | (34) July 6, 2007 12:35 AM
Posted by: analyst | (33) July 6, 2007 12:12 AM
Posted by: Cloud | (32) July 5, 2007 11:07 PM
Posted by: analyst | (31) July 5, 2007 10:16 PM
Posted by: mike | (30) July 5, 2007 12:48 AM
Posted by: Atry | (29) July 4, 2007 02:08 PM
Posted by: Atry | (28) July 4, 2007 02:01 PM
Posted by: Atry | (27) July 4, 2007 01:59 PM
Posted by: Cloud | (26) July 4, 2007 01:18 PM
Posted by: Atry | (25) July 4, 2007 01:07 PM
Posted by: Cloud | (24) July 4, 2007 12:57 PM
Posted by: Atry | (23) July 4, 2007 11:04 AM
Posted by: analyst | (22) July 4, 2007 10:54 AM
Posted by: analyst | (21) July 4, 2007 10:44 AM
Posted by: dayn9 | (20) July 4, 2007 10:33 AM
Posted by: mike | (19) July 4, 2007 10:02 AM
Posted by: mike | (18) July 4, 2007 09:58 AM
Posted by: mike | (17) July 4, 2007 09:45 AM
Posted by: Cloud | (16) July 4, 2007 01:50 AM
Posted by: analyst | (15) July 3, 2007 10:38 PM
Posted by: analyst | (14) July 3, 2007 10:36 PM
Posted by: mike | (13) July 3, 2007 10:03 PM
Posted by: verybook | (12) July 3, 2007 09:38 PM
Posted by: Cloud | (11) July 3, 2007 06:38 PM
Posted by: Anonymous | (10) July 3, 2007 06:16 PM
Posted by: analyst | (9) July 3, 2007 05:53 PM
Posted by: Cloud | (8) July 2, 2007 07:43 PM
Posted by: cat | (7) July 2, 2007 06:00 PM
Posted by: Cloud | (6) July 2, 2007 05:14 PM
Posted by: analyst | (5) July 2, 2007 04:20 PM
Posted by: longtrue | (4) July 2, 2007 03:44 PM
Posted by: Atry | (3) July 2, 2007 10:39 AM
Posted by: Atry | (2) July 2, 2007 10:37 AM
Posted by: ccc | (1) July 2, 2007 08:37 AM