流程的反转控制
我们在很多C++书籍中都会看到关于多态的例子,一般是写两个简单的类: classA { virtualintM1(){...}; }; class&nb
我们在很多C++书籍中都会看到关于多态的例子,一般是写两个简单的类:
class A
{
virtual int M1(){...};
};
class B:public class A
{
virtual init M1(){};
};
然后给出一个使用方法:
B *b=new B;
A *a=b;
a->M1();
此时执行B::M1();
这个例子对于解释C++的多态语法是足够了,然而它没有揭示出我们为什么要用多态:既然我们能直接创建B,为什么我们不直接使用B.M1()呢?如果这样,多态与继承还有什么区别呢?
有些书上会给稍微好一点的例子,再给一个函数:
void test(A &a)
{
a.M1();
}
然后给出一个使用方法:
B *b=new B;
test(*b);
这已经部分触及到了多态的真正意义。
在一个有工程意义的代码中,我们的函数远比这样的示例程序复杂,它会实现一个控制流程,在控制流程的某一点,我们调用了a.M1(),这使得流程的不变部分与可变部分分离。当我们完成一个流程后,我们可以不再关心流程的实现,而只关心给我们预留出来的hook,这就叫做反转流程(inversion of control),这正是基本上所有的框架(framework)的实现基础。这种区分使得程序员有了两个类别的分工:框架的编写者与使用者,其中使用者常被称为用户或者客户。
在编程世界里,我们处在不同的角色当中,对于C++而言,在很多书籍中我们都会看到“用户”,这个词对于像我这些写行业软件的人,最容易弄混。对我而言,“用户”是指使用我开发出来的软件的人,而书中大部分情况下的“用户”是指使用框架(或者类库)的二次开发程序员。
顺便提一句,在反转流程中(inversion of control)中使用到多态时,基类指针指向了真正的对象,这个过程叫做对象交换(Ojbect interchangable)。
有很多代码的实现不是简单用一个函数来实现,因为它不符合面向对象的编程思想。更常用的方法是,我们在框架的主控对象(这种对象有时也叫做主动对象,Active Object)中保留hook的基类指针,在用户代码中新写了对hook的派生类后,使用主控对象的register函数,将该新的派生类对象“注册到”主动对象中,此时主控对象会使用C++的多态特性实现动态绑定。这涉及到设计模式的边缘,在未来有暇时聊到设计模式时再细谈。
总之,我理解的多态的真正意义在于实现流程的反转控制。如果我们的工程足够大,要求足够的灵活性,我们也可以制作自己的框架。然而作为一个实用的程序员,我想强调的一点时,没有先进的技术,只有合适的技术。不是说继承就比包含(composition)好,不用多态就不是完美的C++程序。每个特性都有它的特定用途,理解它的真正应用场合,只能通过漫长的实践过程。 本文作者:佚名 来源:http://www.zxbc.cn/
CIO之家 www.ciozj.com 微信公众号:imciow
免责声明:本站转载此文章旨在分享信息,不代表对其内容的完全认同。文章来源已尽可能注明,若涉及版权问题,请及时与我们联系,我们将积极配合处理。同时,我们无法对文章内容的真实性、准确性及完整性进行完全保证,对于因文章内容而产生的任何后果,本账号不承担法律责任。转载仅出于传播目的,读者应自行对内容进行核实与判断。请谨慎参考文章信息,一切责任由读者自行承担。
延伸阅读