C++虚函数详解

C++虚函数详解

ID:44713638

大小:50.41 KB

页数:16页

时间:2019-10-25

C++虚函数详解_第1页
C++虚函数详解_第2页
C++虚函数详解_第3页
C++虚函数详解_第4页
C++虚函数详解_第5页
资源描述:

《C++虚函数详解》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:  virtual函数返回值类型虚函数名(形参表)  {函数体}派生类可以重置(“覆盖”)基类的非虚函数吗?EffectiveC++有条款说明这个问题的条款37:决不要重新定义继承而来的非虚函数有两种方法来看待这个问题:理论的方法和实践的方法。让我们先从实践的方法开始。毕竟,理论家一般都很耐心。假设类D公有继承于类B,并且类B中定义了一个公有成员函数mf。mf的参数和返回类型不重要,所以假设都为void。换句话说,我这么写:classB{p

2、ublic: voidmf(); ...};classD:publicB{...};甚至对B,D或mf一无所知,也可以定义一个类型D的对象x,Dx;                         //x是类型D的一个对象那么,如果发现这么做:B*pB=&x;                  //得到x的指针pB->mf();                    //通过指针调用mf和下面这么做的执行行为不一样:D*pD=&x;                  //得到x的指针pD->mf();                    //通过指针调用mf

3、你一定就会感到很惊奇。因为两种情况下调用的都是对象x的成员函数mf,因为两种情况下都是相同的函数和相同的对象,所以行为会相同,对吗?对,会相同。但,也许不会相同。特别是,如果mf是非虚函数而D又定义了自己的mf版本,行为就不会相同:classD:publicB{public: voidmf();                 //隐藏了B::mf;参见条款50 ...};pB->mf();                    //调用B::mfpD->mf();                    //调用D::mf行为的两面性产生的原因在于,象B::m

4、f和D::mf这样的非虚函数是静态绑定的(参见条款38)。这意味着,因为pB被声明为指向B的指针类型,通过pB调用非虚函数时将总是调用那些定义在类B中的函数----即使pB指向的是从B派生的类的对象,如上例所示。相反,虚函数是动态绑定的(再次参见条款38),因而不会产生这类问题。如果mf是虚函数,通过pB或pD调用mf时都将导致调用D::mf,因为pB和pD实际上指向的都是类型D的对象。所以,结论是,如果写类D时重新定义了从类B继承而来的非虚函数mf,D的对象就可能表现出精神分裂症般的异常行为。也就是说,D的对象在mf被调用时,行为有可能象B,也有可能象D,决

5、定因素和对象本身没有一点关系,而是取决于指向它的指针所声明的类型。引用也会和指针一样表现出这样的异常行为。实践方面的论据就说这么多。我知道你现在想知道的是,不能重新定义继承而来的非虚函数的理论依据是什么。我很高兴解答。条款35解释了公有继承的含义是"是一个",条款36说明了为什么"在一个类中声明一个非虚函数实际上为这个类建立了一种特殊性上的不变性"。如果将这些分析套用到类B、类D和非虚成员函数B::mf,那么,·适用于B对象的一切也适用于D对象,因为每个D的对象"是一个"B的对象。·B的子类必须同时继承mf的接口和实现,因为mf在B中是非虚函数。那么,如果D重

6、新定义了mf,设计中就会产生矛盾。如果D真的需要实现和B不同的mf,而且每个B的对象----无论怎么特殊----也真的要使用B实现的mf,那么,每个D将不"是一个"B。这种情况下,D不能从B公有继承。相反,如果D真的必须从B公有继承,而且D真的需要和B不同的mf的实现,那么,mf就没有为B反映出特殊性上的不变性。这种情况下,mf应该是虚函数。最后,如果每个D真的"是一个"B,并且如果mf真的为B建立了特殊性上的不变性,那么,D实际上就不需要重新定义mf,也就决不能这样做。不管采用上面的哪一种论据都可以得出这样的结论:任何条件下都要禁止重新定义继承而来的非虚函数

7、。    派生类和基类的关系:1:派生类对象可以使用基类的方法,条件是方法不是私有的。2:基类指针可以在不进行显示类型转换的情况下指向派生类对象;基类引用可以在不进行显示类型转换的情况下引用派生类对象;但基类指针或引用只能用于调用基类的方法;3:不可以将基类对象和地址赋给派生类引用和指针;4:将派生类引用或者指针转换成为基类引用或指针被称为向上强制转换,不需要进行显示类型转换。将基类指针或引用转换为派生类指针或引用成为向下强制转换。5:如果基类函数中没有使用虚函数,使用类型转换才有静态编译;如果基类中有虚函数,则采用动态联编。编译器处理虚函数的方法:给每个对象

8、添加一个隐藏成员。隐藏成员中保存了一个

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。