[c++ primer plus]虚函数的返回类型协变

派生类转换为基类,hierarchy向上走,称为upcasting;基类转换为派生类,hierarchy向下走,称为downcasting。downcasting是不安全的,一般不被允许。

含有虚函数的类,编译器给每个对象添加一个隐藏成员,该成员保存一个指向函数地址数组的指针。这个函数地址数组包含了类的所有虚函数地址。如果派生类覆盖了基类的虚函数,那么这个数组中相应的元素也被覆盖;如果派生类增加了一个虚函数,那么会在数组中增加一个元素。不管虚函数数目是1还是10,都只在对象中添加一个地址成员,只是表的大小不同而已。

返回类型协变

覆盖要求函数具有完全相同的入参

一般覆盖具有相同的返回值,否则会提示错误

virtual   double  area ()  const   =   0 ;
virtual   float  area ()  const  ;  // 编译器提示错误,返回类型不同

这个规则对返回类型协变而言,则有所放松。覆盖的返回值不区分基类或派生类。从语意上理解,一个派生类也是一个基类。如下:

   Class ShapeEditor  {……} ;
Class Shape 
{
public:
    
virtual const ShapeEditor & getEditor () const = 0//Factory Method
}
;

Class Circle;
Class CircleEditor : 
public  ShapeEditor  { … } ;
Class Circle : Public Shape
{
public:
    
const CircleEditor &getEditor () const ;
}
;

 在这个例子中,注意CircleEditor必须在Circle::getEditor的声明之前被完整地定义(而不能仅仅声明),
因为编译器必须知道CircleEditor对象的布局,才能执行适当的地址操纵,从而将一个CircleEditor引用
(或指针)转换为一个ShapeEditor引用(或指针)。

协变返回类型的优势在于,总是可以在适当程度的抽象层面工作。若我们是处理Shape,将获得一个抽象的ShapeEditor;若正在处理某种具体的形状类型,比如Circle,我们就可以直接获得CiecleEditor.协变返回机制将我们从这样的一种处境解脱出来:不得不使用易于出错的转换操作来“重新”提供类型信息,而这种信息是一开始就不应该丢掉的:(那么,对于友元,派生的operator+,怎么样调用基类的operator+呢?)

Shape  *  s  =  getACircleOrOtherShape ();
Const ShapeEditor 
& sed  =  s -> getEditor();
Ciecle 
* = getACircle();
Const CircleEditor 
& ced  =  c -> getEditor();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值