一、协变的应用条件
前方已经分析过,逆变在C++应用受限非常大,而且应用也比较少,所以这里就只分析一下协变。在前面分析了协变和逆变的技术细节,今天分析一下它的应用。首先看一下它的应用条件,其实在前面的文章中已经分散在各个地方说明了,这里再总结一下:
1、必须是在有继承关系的类中才可以使用
2、必须是向抽象转换即子类对象可以替代父类对象即C++中必须是指针或引用
3、如果用在返回类型协变上,必须是虚拟函数即多态应用的重写函数
4、如果用在返回类型协变上,返回类型必须有继承关系
注意:如无特殊说明,本文的对象指的就是指针或引用。
二、协变的应用场景
在分析了其限制条件后,看一下其应用的场景:
1、类似工厂模式的设计场景
可以根据实际情况返回适当的子类对象而非以前必须返回父类对象,避免或减少父子类对象的转换
2、模板应用
正如前面文章提到的,将子类的应用最大化,在模板的开发中,可以更好的确定性的应用对象类型并更好的发挥多态的效果
3、继承下的扩展
协变可以更好的保持继承下的数据类型的准确性,从而安全的进行子类型的处理,进而达到方便扩展的目的
4、继承类型数据的处理
这种是协变的最典型的应用场景,比如父对象的指针可以指向子对象。
三、协变的问题
协变在C++中其实受限还是比较多的,同时协变也会引起一些运行上的问题,需要开发者引起注意 :
1、效率的问题
只要有转换的过程,就会有效率的损失(包括内存的开销),即使在最好的情况下,也只可能是相等。同时返回类型协变是在虚拟函数下进行的,而这一定会有效率的损失。
2、代码的可维护性问题
由于使用了协变,使得代码的可读性下降,进而导致维护成本的增加
3、与CRTP的不致问题
这个一般开发者可以忽略,毕竟使用协变的少,使用CRTP的更少。二者在一起的更少之又少。
四、协变使用的原则
针对上面的问题,对协变的应用有几个原则:
1、尽量不在复杂场景下应用协变,特别是返回值协变
2、尽量不综合应用协变,即或者只用数据类型的协变或者只用返回值类型的协变
3、协变处进行清晰的注释
五、总结
其实C++中使用协变的场景应用本来就不多,所以很多开发者应也不用有什么太多的想法。抓住本质,有真实应用的场景的时候儿认真去做就不有问题。再说,即使有问题,反而是好事,可以更好的增加对协变的理解程度。这就是所谓的塞翁失马!