C++中的继承与虚函数各种概念
http://www.cnblogs.com/xkfz007/archive/2012/02/16/2354444.html
虚继承与一般继承
虚继承和一般的继承不同,一般的继承,在目前大多数的C++编译器实现的对象模型中,派生类对象会直接包含基类对象的字段。而虚继承的情况,派生类对象不会直接包含基类对象的字段,而是通过一个间接的指针去存取基类对象中的字段。
继承的特性
继承是面向对象中引入的重要特性之一,它的一个重要的特点就是子类是父类,父类不是子类。也就是说:
1.如果基类指针指向子类对象(pbase=&pchild),则该指针只能调用基类定义了的函数;(因为这个地方是静态绑定,而静态绑定所依赖的就是指针声明时的类型)
2.如果子类指针指向基类对象(pchild=(child *)pbase),则会出问题;(因为子类中可能有一些方法是基类中没有的,在编译时静态绑定一些子类中特有的方法可能导致运行时没有这个方法)
3.如果基类和子类定义了同名的函数,则到底调用什么函数,必须视该指针的原始类型而定,而不是视指针实际指向的对象类型而定。(这个地方其实就是一般继承和虚函数继承的区别:一般继承静态绑定,所以依据指针声明的原始类型,而虚函数是进行动态绑定的,它是根据实际指针所指向的对象。)
4.就算子类继承了父类的某个函数(而未改写它),该函数依然被视为父类的,该函数依然属于父类的域中,该函数中使用的普通函数(非虚函数)依然被视为父类的函数。
5.私有变量的继承性:私有变量对子类是不可见的,即使是子类从父类继承下来了,也仍然是不可见的,它仅仅能被父类的函数(没有在子类中改写或重写过的函数)操作。
6. this指针:类的成员函数的参数中有一个隐藏的参数this指针,这保证了被继承的成员函数归属对象的正确性和无混淆性。
虚函数的实现原理
正是因为继承的这个特点,虚函数的加入似乎就是顺理成章的事情了。虚函数简化并明确了软件和各种类库的设计以及维护。
一般的函数在编译链接时就进行了绑定,这称之为早绑定。由于信息量不够,所以只能依赖于调用它的对象或指针的声明类型实现绑定。也就是侯俊杰说的,如果基类和子类定义了同名的函数,那么到底调用哪个类的函数,必须视该指针的原始类型而定,而不是视指针实际指向的对象类型而定。因为赋值的动作还没有产生。
而虚函数则不是这样。虚函数实现的机制是晚绑定,它在编译链接时并没有与某个对象绑定----这也正是虚函数能实现多态(以相同代码调用不同函数)的原因所在。当编译器对程序进行编译碰到虚函数时,将不会赋予一个地址,而是插入一段汇编代码。每个包含虚函数的类都会由编译器产生一个虚函数表和一个虚函数表指针,其中虚函数表指针放在每个类的首地址处(也许不是,不过反正地址偏移量在每个类所占内存中是固定的,这个在其他文章中有专门详述虚函数表)。当程序执行时,碰到对虚函数的调用,则通过插入的汇编代码到当前类的地址中找到虚函数表指针,通过虚函数的序号找到需要调用的虚函数。注意,一个系列的类的虚函数表中某一个函数的序号是一样的。而且,编译器会保证在使用父类指针操作子类对象时只能在父类已有的虚函数上实现虚函数的机制。
这里还有一个虚函数的默认参数的问题。虚函数是动态绑定的,而默认参数则是静态绑定的,所以在虚函数中使用默认参数可以说是不符合逻辑的。如果子类改写了父类虚函数中的默认参数,当使用多态特性时,会出现调用子类的虚函数,使用的却是父类中的对应虚函数的默认参数的情况。
虚函数适用的两种场合
1.某个子类中调用继承下来的非虚函数中有对已改写的虚函数的调用。
值得注意的是,在某个子类中调用继承下来的未改写的非虚函数中有对已改写的虚函数的调用时,调用的是当前子类中改写过的虚函数;若该非虚函数中有对已改写的非虚函数的调用时,调用的是父类的非虚函数(也是因为晚绑定)。这是MFC的惯用手法。
2.使用向上映射(父类指针=子类指针),实现代码的重用
3.父类中的析构函数。当一个类确信不会成为任何类的父类时,它的析构函数是不需要设置成虚函数的;当一个类肯定会成为某个类的父类时,虚析构函数是必要的。因为若是父类中的析构函数是非虚的,则当用一个父类的指向子类的指针delete子类时,这种行为在C++标准中并没有被定义,是十分危险的。
继承中的接口及其实现
经过以上分析可知,虚函数实际上就是继承中的一种接口。继承中一共有纯虚函数、非纯虚函数和非虚函数三种接口,它们在子类中的处理如下:
1.纯虚函数:所有子类必须强制性地改写,否则会报错。这是一种仅仅继承接口的方法。
2.非纯虚函数:又被称为简单虚函数,可以在基类中有自己的实现(默认的动作),子类不一定要改写,这是一种继承接口及其默认实现的方法。
3.非虚函数:子类最好不要改写,这是一种强制性地继承接口及其实现的方法,表示的是一种共性。
当在同一个类中存在同名但是参数不同的函数,叫作overloading(重载);子类改写父类的虚函数,叫做overriding(覆盖);子类改写父类的非虚函数,叫做redefining(重定义),这是不推荐的。
虚函数、纯虚函数、虚基类、抽象类、虚函数继承、虚继承-------各种概念解释
虚函数:
虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。是C++中多态性的一个重要体现,利用基类指针访问派生类中的成员函数,这种情况下使用虚函数,这种情况下采用的是动态绑定技术。
虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:
virtual函数返回值类型虚函数名(形参表)
{函数体}
动态绑定:
基类指针是调用派生类的中的成员函数还是调用基类中的成员函数要到程序运行时确定。主要要看指针所指向的对象。
纯虚函数:
纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”
virtual void funtion1()=0
虚基类、抽象类:
包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。
虚函数继承:
虚函数继承就是覆盖。即基类中的虚函数被派生类中的同名函数所覆盖。是实现多态的方法。
虚继承:
解决多重继承中派生类成员函数调用模糊问题。比如类A中有一个函数print(),类B继承A,类C继承A,类D继承类B和类C,这个时候,类D中就有两个print函数,一个是从B继承得到的,一个是从C继承得到的,则类D的对象调用print函数就会出现print模糊的编译错误。解决办法:类B虚拟继承A。类C虚拟继承A,类D继承B,C时,只拷贝A中的数据成员和函数成员一次,再遇到拷贝时候就忽略了!
虚继承就是为了节约内存的,他是多重继承中的特有的概念。适用与菱形继承形式。
如:类B、C都继承类A,D继承类B和C。为了节省内存空间,可以将B、C对A的继承定义为虚拟继承,此时A就成了虚拟基类。
class A;
class B:public vitual A;
class C:public vitual A;
class D:public B,public C;
参考:http://www.haogongju.net/art/1069038
http://www.diybl.com/course/3_program/c++/cppsl/2008520/117246.html
相关推荐
2、熟练掌握虚函数的作用及其使用方法。 3、掌握静态关联和动态关联的概念和用法。 4、理解纯虚函数和抽象类的概念和用法。 (二)实验内容 1、定义一个类A,在A中有两个私有的整型变量a和b,定义构造函数对a和b进行...
C++实验六 多态性和虚函数的应用 课程 实验报告 作业参考的良品!
c++里,指针和引用是很重要的概念,这个程序不仅对指针和引用做了说明、使用,而且对子类不能继承父类虚函数也做了说明。
虚函数是C++中实现多态的机制。下面通过几个小程序实验来复习一下虚函数的概念用法
在面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念。因为它充分体现 了面向对象思想中的继承和多态性这两大特性,在C++语言里应用极广。比如在微软的MFC类库中,你会发现很多函数都有virtual...
虚函数和纯虚函数的理解区别,最重要的是知道虚函数和纯虚函数的用法
第9章 多态性与虚函数 本章学习要求: 虚函数 多态性 静态与动态联编 9.1 多态性的概念 9.2 虚函数 9.3 静态绑定与动态绑定 9.4 纯虚函数和抽象类
C++概念总结,概念,对象的引用,构造函数,析构函数,虚函数,纯虚函数,函数重载,等等的概念总结!!!
虚基类与虚函数 虚基类的概念 在C++语言中,一个类不能被多次说明为一个派生类的直接基类,但可以不止一次地成为间接基类。这就导致了一些问题。为了方便 说明,先介绍多继承的“类格”表示法。
首先先解释一下多态的概念,多态是c++的特点之一,关于多态,简而言之就是 用父类的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数,这种方法呢,可以让父类的指针具有多种形态,也就是说不需要...
C++程序设计课件 函数第12章 多态性与虚函数 12.1 多态性的概念 12.2 一个典型的例子 12.3 虚函数 12.4 纯虚函数与抽象类
2013级,C++程序设计课件。第12章 多态性与虚函数,内容 12.1 多态性的概念 12.2 一个典型的例子 12.3 虚函数 12.4 纯虚函数与抽象类 课程主页在:http://blog.csdn.net/sxhelijian/article/details/11890759
本文通过案例来阐述多态的概念和虚函数的使用,这是c++的重要性质之一,是面向对象概念的重要部分。
虚函数可以毫不夸张的说是C++最重要的特性之一,我们先来看一看虚函数的概念。 在基类的定义中,定义虚函数的一般形式为: virtual 函数返回值类型 虚函数名(形参表) { 函数体 } 为什么说虚函数是C++最重要的...
1、讲解和演示虚函数的概念与作用; 2、讲解和演示虚函数与多态在开发中的应用;
12.1 多态性的概念 12.2 一个典型的例子 12.3 虚函数 12.4 纯虚函数与抽象类
定义一个函数为虚函数,不代表函数为不被实现的函数。 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。 定义一个函数为纯虚函数,才代表函数没有被实现。 定义纯虚函数是为了实现一个接口,起到一个...
内容主要为:C++语言简介、面向对象的基本概念、类和对象进阶、运算符重载、类的继承与派生、多态与虚函数、输入/输出流、文件操作、函数模板与类模板九个章节的相关知识点总结,其中包括知识点介绍,知识点分析,...
主要介绍了C++中虚函数与纯虚函数的用法,是非常重要的概念,需要的朋友可以参考下
编写一个程序,计算三角形、正方形和圆形这3种图形的面积,并用相关数据进行测试。...掌握虚函数和纯虚函数的概念。 理解静态多态性和动态多态性,学习使用虚函数的继承实现动态多态性。 了解抽象类的概念。