整站网站优化,动画制作公司排名,手机网站设计建设,ps做的网站首页虚继承与一般继承 虚继承和一般的继承不同#xff0c;一般的继承#xff0c;在目前大多数的C编译器实现的对象模型中#xff0c;派生类对象会直接包含基类对象的字段。而虚继承的情况#xff0c;派生类对象不会直接包含基类对象的字段#xff0c;而是通过一个间接的指针去… 虚继承与一般继承 虚继承和一般的继承不同一般的继承在目前大多数的C编译器实现的对象模型中派生类对象会直接包含基类对象的字段。而虚继承的情况派生类对象不会直接包含基类对象的字段而是通过一个间接的指针去存取基类对象中的字段。 继承的特性 继承是面向对象中引入的重要特性之一它的一个重要的特点就是子类是父类父类不是子类。也就是说 1. 如果基类指针指向子类对象pbasepchild,则该指针只能调用基类定义了的函数因为这个地方是静态绑定而静态绑定所依赖的就是指针声明时的类型 2. 如果子类指针指向基类对象pchildchild *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 虚基类、抽象类 包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数所以不能定义抽象类的对象。 虚函数继承 虚函数继承就是覆盖。即基类中的虚函数被派生类中的同名函数所覆盖。 是实现多态的方法。 View Code 虚继承 解决多重继承中派生类成员函数调用模糊问题。比如类A中有一个函数print()类B继承A类C继承A类D继承类B和类C这个时候类D中就有两个print函数一个是从B继承得到的一个是从C继承得到的则类D的对象调用print函数就会出现print模糊的编译错误。解决办法类B虚拟继承A。类C虚拟继承A类D继承BC时只拷贝A中的数据成员和函数成员一次再遇到拷贝时候就忽略了 虚继承就是为了节约内存的他是多重继承中的特有的概念。适用与菱形继承形式。 如类B、C都继承类AD继承类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 一个介绍虚函数的很好的pptpdf下载ppt下载