C++学习之虚函数继承和虚继承

虚函数的定义要遵循以下重要规则:

1.如果虚函数在基类与派生类中出现,仅仅是名字相同,而形式参数不同,或者是返回类型不同,那么即使加上了virtual关键字,也是不会进行晚绑定的。

2.只有类的成员函数才能说明为虚函数,因为虚函数仅适合用与有继承关系的类对象,所以普通函数不能说明为虚函数。

3.静态成员函数不能是虚函数,因为静态成员函数的特点是不受限制于某个对象。

4.内联(inline)函数不能是虚函数,因为内联函数不能在运行中动态确定位置。即使虚函数在类的内部定义定义,但是在编译的时候系统仍然将它看做是非内联的。

5.构造函数不能是虚函数,因为构造的时候,对象还是一片未定型的空间,只有构造完成后,对象才是具体类的实例。

6.析构函数可以是虚函数,而且通常声明为虚函数。

在一个有虚函数的类中,编译器会设立一个虚函数表(虚表)用来记录对应的虚函数地址。每个地址对应一个虚指针,指针的大小为4个字节(编译器一般以4的倍数对其地址)。虚表为顺序存储。在类的实例对象中,会有一个虚表指针,用来指向虚表。

虚继承是为了解决多重继承而设计的,避免重复拷贝。如下:

图(a),(b),(c)表示B继承自A,C继承自A,D继承自B和C,那么因为B和C都继承自A,因此会出现d的情况,在类D中会出现两个A,出现了重复拷贝,为了节省空间,可将B,C对A的继承定义为虚继承,A则成为虚基类,则继承图便成为图(e)。

代码如下:

【代码】


1

2

3

4

class A;

class B:public virtual A;  //定义成虚继承

class C:public virtual A;  //定义成虚继承

class D:public B,public C; //只会出现一个A

来自为知笔记(Wiz)

附件列表

时间: 2024-11-04 20:18:22

C++学习之虚函数继承和虚继承的相关文章

C++ Primer 学习笔记_70_面向对象编程 --纯虚函数、容器与继承

面向对象编程 --纯虚函数.容器与继承 I.纯虚函数 在函数形参后面写上 =0 以指定纯虚函数: class Disc_item : public Item_base { public: double net_price(size_t) const = 0; //指定纯虚函数 }; 将函数定义为纯虚函数能够说明,该函数为后代类型提供了可以覆盖的接口,但是这个类的版本绝不会调用.重要的是,用户将不能创建Disc_item类型的对象. Disc_item discount; //Error Bulk

C++ Primer 学习笔记_70_面向对象编程 -纯虚函数、器皿与继承

面向对象编程 --纯虚函数.容器与继承 I.纯虚函数 在函数形参后面写上 =0 以指定纯虚函数: class Disc_item : public Item_base { public: double net_price(size_t) const = 0; //指定纯虚函数 }; 将函数定义为纯虚函数能够说明,该函数为后代类型提供了可以覆盖的接口,但是这个类的版本绝不会调用.重要的是,用户将不能创建Disc_item类型的对象. Disc_item discount; //Error Bulk

继承中的虚函数、纯虚函数、普通函数

一.虚函数 被virtual关键字修饰的类成员函数就是虚函数.虚函数的作用就是实现运行时的多态性,将接口与实现分离.简单理解就是相同函数有着不同的实现,但因个体差异而采用不同的策略. 基类中提供虚函数的实现,为派生类提供默认的函数实现.派生类可以重写基类的虚函数以实现派生类的特殊化.如下: class Base{ public: virtual void foo() { cout<<"Base::foo() is called"<<endl; } }; clas

C++ 虚函数 、纯虚函数、接口的实用方法和意义

也许之前我很少写代码,更很少写面向对象的代码,即使有写多半也很容易写回到面向过程的老路上去.在写面向过程的代码的时候,根本不管什么函数重载和覆盖,想到要什么功能就变得法子的换个函数名字,心里想想:反正函数重载本质也就是入栈了两个不同的函数. 回过头来讲,让我了解标题这三个概念的实际用处,还是在于我这第四次重写毕业论文的代码,将它改写成面向对象的时候,才理解的.在面向对象设计的过程中, 类是从抽象逐渐具体起来的,父类可以是非常非常抽象的东西,而最终实例化的子类就非常具体了.在这个继承的过程中,不断

抽象类,虚函数,纯虚函数的意义

C语言是面向过程的语言,C++是面向对象的语言,区分它们面向什么的重要区别在于C++比C多个类.那么在我看来,抽象就是类的升华. 一般刚学习C++的时候,抽象这个东西给人最大的感觉就是太抽象,很难理解.心里总是想着,其实这样或那样就能解决这个问题了,为什么要学这个?增加一个抽象类还增加一段代码,费事不说还不容易理解,所以当时我对抽象还是很抗拒的.但是当工作中真正用到这个的时候,就觉得这个东西真是太好了,任何其它的方案都无法代替抽象. 为什么这样说呢?首先C++是强类型语言,对于一个数组或链表来讲

关于虚函数与纯虚函数的区别

转自: https://blog.csdn.net/hackbuteer1/article/details/7558868 注: 该博主是个大牛,虽然早已经不更新了,但是分享了很多数据结构的面试题,值得翻阅学习. 重点笔记摘要如下: 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数.(我想这就是虚函数的意义吧,下面基本都在讲纯虚函数和抽象类) 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实现一个接口,起到一个规范的

c++中虚函数和纯虚函数定义

只有用virtual声明类的成员函数,使之成为虚函数,不能将类外的普通函数声明为虚函数.因为虚函数的作用是允许在派生类中对基类的虚函数重新定义.所以虚函数只能用于类的继承层次结构中. 一个成员函数被声明为虚函数后,在同一类族中的类就不能再定义一个非virtual的但与该虚函数具有相同的参数(包括个数和类型)和函数返回值类型的同名函数. 根据什么考虑是否把一个成员函数声明为虚函数? ①  看成员函数所在的类是否会作为基类 ② 看成员函数在类的继承后有无可能被更改功能,如果希望更改其功能的,一般应该

虚函数和纯虚函数的作用与区别

http://blog.csdn.net/xwpc702/article/details/8670025 虚函数为了重载和多态的需要,在基类中是有定义的,即便定义是空,所以子类中可以重写也可以不写基类中的此函数!纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数!虚函数引入原因:为了方便使用多态特性,我们常常需要在基类中定义虚函数.class Cman{public:virtual void Eat(){……};void Move();private:};class C

C++ 虚函数与纯虚函数 浅析

[摘要] 本文首先简述虚函数与纯虚函数的定义,然后分析比较两者的区别与联系(DWS). [正文] 1)虚函数与纯虚函数有什么区别? 虚函数,不代表函数为不被实现的函数,为了允许用基类的指针来调用子类的这个函数:允许被其子类重新定义的成员函数. 纯虚函数,才代表函数没有被实现,为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数. 2)虚就虚在所谓"推迟联编"或者"动态联编"上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的.

C++虚函数和纯虚函数

只有用virtual声明类的成员函数,使之成为虚函数,不能将类外的普通函数声明为虚函数.因为虚函数的作用是允许在派生类中对基类的虚函数重新定义.所以虚函数只能用于类的继承层次结构中. 一个成员函数被声明为虚函数后,在同一类族中的类就不能再定义一个非virtual的但与该虚函数具有相同的参数(包括个数和类型)和函数返回值类型的同名函数. 根据什么考虑是否把一个成员函数声明为虚函数? ①  看成员函数所在的类是否会作为基类 ② 看成员函数在类的继承后有无可能被更改功能,如果希望更改其功能的,一般应该