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

本文探讨了C++中的派生类与基类之间的转换,包括upcasting和downcasting的概念及其安全性。深入解析了虚函数的工作原理,以及返回类型协变如何在不改变参数的情况下放宽对返回类型的限制,提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

派生类转换为基类,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();
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值