Chinaunix首页 | 论坛 | 博客
  • 博客访问: 240333
  • 博文数量: 38
  • 博客积分: 710
  • 博客等级: 上士
  • 技术积分: 315
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-06 10:52
文章分类

全部博文(38)

文章存档

2016年(1)

2015年(10)

2014年(1)

2013年(7)

2011年(9)

2010年(10)

我的朋友

分类: C/C++

2010-12-06 22:07:47

赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员,而且所有成员的访问控制属性也和基类完全相同。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。赋值兼容规则中所指的替代包括以下的情况:
  ·派生类的对象可以赋值给基类对象。

  ·派生类的对象可以初始化基类的引用。
  ·派生类对象的地址可以赋给指向基类的指针。
  在替代之后,派生类对象就可以作为基类的对象使用,但只能使用从基类继承的成员。
  如果B类为基类,DB类的公有派生类,D类中包含了基类B中除构造、析构函数之外的所有成员,这时,根据赋值兼容规则, 在基类B的对象可以使用的任何地方,都可以用派生类的对象来替代。在如下程序中, b1B类的对象,d1D的对象。
    clasS B
    {…}
    class Dpublic B
    {…}
    B b1*pbl
    D d1
  这时:
  派生类对象可以赋值给基类对象,即用派生类对象中从基类继承来的成员,逐个赋值给基类对象的成员:
    b1=d1
  派生类的对象也可以初始化基类对象的引用:
    B &bb=d1
  派生类对象的地址也可以赋给指向基类的指针:
    pb1=&d1;
  由于赋值兼容规则的引入,对于基类及其公有派生类的对象,我们可以使用相同的函数统一进行处理(因为当函数的形参为基类的对象时, 实参可以是派生类的对象) 而没有必要为每一个类设计单独的模块,从而大大提高了程序的效率。 这正是C++的又一重要特色,即多态性,可以说,赋值兼容规则是多态性的重要基础之一。
:赋值兼容规则实例。
  本例中,基类B0以公有方式派生出B1类,B1类再作为基类以公有方式派生出D1类,基类B0中定义了成员函数display() 在派生类中对这个成员函数进行了覆盖。程序代码如下:
    //** chap13_2.cpp
    #includeh>
    class B0 //基类B0声明
    {
     publiC
      v0id display(){c0ut<<"B0::display()"<}
         //公有成员函数
    }
    class B1publicB0 //公有派生类B1声明
    {
     public
      v0id display(){c0ut<<"Bi::display()"<}
         //公有成员函数
    }
    class D1public B1 //公有派生类B1声明
    {
     public
      v0id display(){c0ut<<”D1::display()”<}
          //公有成员函数
    }
    v0id fun(B0 *ptr) //普通函数
    { //参数为指向基类对象的指针
     ptr->display() //”对象指针—>成员名
    }
    v0id main() //主函数
    {
     B0 b0 //声明B0类对象
     B1 bl //声明B1类对象

     D1 dl //声明D1类对象
     B0 *p //声明B0类指针
     p=&b0 //B0类指针指向B0类对象
     fun(p)
     p=&b1 //B0类指针指向B1类对象
     fun(p)
     p=&d1 //B0类指针指向D土类对象
     fun(p)
    }
  这样,通过对象名.成员名或者对象指针->成员名的方式,就可以访问到各派生类中新添加的同名成员。虽然根据赋值兼容原则,可以将派生类对象的地址赋值给基类B0的指针,但是通过这个基类类型的指针,却只能访问到从基类继承的成员。
  在程序中,定义了一个形参为基类B0类型指针的普通函数fun 根据赋值兼容规则,可以将公有派生类对象的地址赋值给基类类型的指针,这样,使用fun函数就可以统一对这个类族中的对象进行操作。 程序运行过程中,分别把基类对象、 派生类B1的对象和派生类D1的对象赋值给基类类型指针p,但是,通过指针p,只能使用继承下来的基类成员。也就是说,尽管指针指向派生类D1的对象,fun函数运行时通过这个指针只能访问到D1类从基类B0继承过来的成员函数display,而不是D1类自己的同名成员函数。因此,主函数中三次调用函数fun的结果是同样的——访问了基类的公有成员函数。程序的运行结果为:

    B0::display
    B0::display
    B0::display

  通过这个例子,我们看到,根据赋值兼容规则,我们可以在基类出现的场合使用派生类进行替代,但是替代之后派生类仅仅发挥出基类的作用。多态的设计方法可以保证在赋值兼容的前提下,基类、派生类分别以不同的方式来响应相同的消息。



但是将上述程序中

class B0 //基类B0声明
    {
     publiC
      v0id display(){c0ut<<"B0::display()"<}
         //公有成员函数
    }

改成

class B0 //基类B0声明
    {
     publiC
      virtual v0id display(){c0ut<<"B0::display()"<}
         //公有成员函数
    }

程序的输出结果就是


             B0::display
    B1::display
    D1::display

即用虚函数实现了多态性。

虚函数的特点:

1,调用在运行时确定,即动态绑定;

2,如果是全局函数调用虚函数,则根据传递形参的不同而执行不同的操作;

如果是各自对象的指针调用虚函数,则根据指针的不同(哪个对象的指针)而选择调用不同的虚函数的版本。








阅读(1540) | 评论(1) | 转发(0) |
0

上一篇:c++中指向类成员的指针

下一篇:const

给主人留下些什么吧!~~

chinaunix网友2010-12-07 15:35:51

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com