4.8.3 基类链
多重继承一直是C++(www.cppentry.com)中引发争论的话题,喜欢它的人和讨厌它的人几乎同样多。总的来说,多重继承是一种强大的面向对象技术,但使用不当也很容易引发诸多问题,比如难以优化和经典的"钻石型"继承。
operators库使用泛型编程(www.cppentry.com)的"基类链"技术解决了多重继承的问题,这种技术通过模板把多继承转换为链式的单继承。
前面当讨论到less_than_comparable<point>这种用法时,我们说它不是继承,然而,现在,我们将看到它居然真的可以实现继承的功能,这从一个方面展示了泛型编程(www.cppentry.com)的强大威力。
operators库的操作符模板类除了接受子类作为比较类型外,还可以接受另外一个类,作为它的父类,由此可以无限串联链接在一起(但要受编译器的模板编译能力限制),像这样:
- demo: x< demo, y<demo, z<demo,...> > >
使用基类链技术,point类的基类部分可以是这样:- boost::less_than_comparable<point, //注意这里
- boost::equality_comparable<point> > //是一个有很大模板参数列表的类
对比一下多重继承的写法:- boost::less_than_comparable<point>, //注意这里
- boost::equality_comparable<point> //有两个类
代码非常相似,区别仅仅在于模板参数列表结束符号(>)的位置,如果不仔细看可能根本察觉不出差距。但正是这个小小的差距,使基类链通过模板组成了一连串的单继承链表,而不是多个父类的多重继承。
例如,如果为point类再增加加法和减法定义,继承列表就是:
- class point:
- less_than_comparable<point, //小于操作
- equality_comparable<point, //相等操作
- addable<point, //加法操作
- subtractable<point //减法操作
- > > > >
- {...}
基类链技术会导致代码出现一个有趣的形式:在派生类的基类声明末尾处出现一长串的>(模板声明的结束符),在编写代码时需要小心谨慎以保证尖括号的匹配,使用良好的代码缩进和换行可以减少错误的发生。