C++ 继承&多态

原创 2016年05月30日 13:35:10

继承&多态

· 访问限定符

*继承访问控制的作用是将继承下来的成员在派生类域内的属性改变而和原本基类的成员访问控制符关。

 所有的基类private成员在派生类里是不可见,但它确确实实被继承下来了。

 基类的protected成员只对继承它的派生类可见,在类外不可使用


· 派生类列表

  在定义派生类的时候我们必须写出派生类列表,但在声明处不可写。


1.虚函数的使用(多态的实现)

#include<iostream>
using namespace std;
class Base
{
private:
     int _base ;
public:
     Base()
            :_base (0)
     {}
     virtual void show()
     {
            cout << "Base::show()" << endl ;
     }
     //....
};
class D :public Base
{
public:
     D()
            :_d (1)
     {}
     void show()
     {
            cout << "D::show()" << endl ;
     }

private:
     int _d ;
};
void Print (Base *pb)
{
     pb-> show();
}
int main ()
{
     Base b;
     D d;
     Print(& b);
     Print(& d);
     getchar();
     return 0;
}


wKioL1btOM-x6FbyAAAJ7xNtKBI508.png

*通过传参的不同使得show函数的输出结果不同,实现的原理是:虚函数表(动态绑定)

*动态绑定:函数的运行版本由实参决定,在函数运行时才进行选择,又称运行时绑定

*规则:基类通常都需要定义一个虚析构函数,无论是否在后面用到

*成员函数如果没有被声明为虚函数并且不是静态函数,那它的解析过程发生在编译阶段而不是运行阶段

*每个类控制自己的成员初始化,不要使用派生类直接初始化基类成员

*派生类必须对它内部重新定义的虚函数进行声明

*任何除了构造函数以外的非静态函数都可以是虚函数


2.虚函数表

 a.单继承

  如上例中代码示,单继承时Base的对象模型如下

wKioL1btOPewHXhWAAAWc8Njv0M657.png

 D的对象模型如下

wKiom1btOJXz7HUgAAAWf_gvT9M244.png

 b.多继承 

#include<iostream>
using namespace std;
typedef void (*PTR)();
class Base
{
private:
     int _base ;
public:
     Base()
            :_base (0)
     {}
     virtual void show()
     {
            cout << "Base::show()" << endl ;
     }
     //...
};
class Base2
{
private:
     int _base2 ;
public:
     Base2()
            :_base2 (2)
     {}
     virtual void show()
     {
            cout << "Base2::show()" << endl ;
     }
     virtual void fun2()
     {
            cout << "Base2::fun2()" << endl ;
     }
     //...
};
class D :public Base,public Base2
{
public:
     D()
            :_d (1)
     {}
     void show()
     {
            cout << "D::show()" << endl ;
     }
     void fun2()
     {
            cout << "D::fun2()" << endl ;
     }
     virtual void fun3()
     {
            cout << "D::fun3()" << endl ;
     }
     virtual void fun4()
     {
            cout << "D::fun4()" << endl ;
     }
private:
     int _d ;
};
void PrintVT (int p )
     //实参是每个类存储虚函数指针的地址,解引用之后代表该类的虚函数指针
{
     PTR ptr = NULL;
     //现在让pi能访问类的虚函数指针
     int *pi = (int *)p;
     int i = 0;
     while (pi [i ])
     {
            ptr = (PTR)pi[i];
            ptr();
            i++;
     }
}
int main ()
{
     //Base b;
     //Base2 b2;
     D d;
     //PrintVT(*(int *)&b);
     //cout << "--------------------" << endl;
     //PrintVT(*(int *)&b2);
     //cout << "--------------------" << endl;
     PrintVT(*( int *)&d );
     cout << "--------------------" << endl ;
     getchar();
     return 0;
 }


 如上述代码,我们发现多继承的虚函数表和单继承由很大的不同之处

 在此不再赘述两个基类的虚表,我们来看派生类的对象模型

wKiom1btOGeSUmyqAAAfqhZS5ZI278.png

 spacer.gif

*我们发现在派生类中有两个虚函数表,并且派生类自己的虚函数被存入了第一个虚函数表

上述代码运行的结果是

wKioL1btOYqgjYTEAAAXcyFD6Kg565.png


tips:

   *在一个对象中继承自基类的部分和派生类的自定义部分不一定是连续存储的

   *如果在基类里定义了一个静态成员那么这个成员是唯一定义的,只存在一个实例

   *含有关键字final的类不可以作为基类被继承

   *动态绑定基于给用基类的指针或者引用绑定对象。除了内置指针外智能指针也是可以做到这样的     类     型转换的

          

C++的多态性:我们把具有继承关系的多个类型称为多态类型,因为我们可以使用这些类型的多种形式而无须在意他们的差异


覆盖:派生类重新定义了基类的虚函数并且他们的函数名,参数列表和返回值都必须相同但是协变的返              回值必须不同。

隐藏:派生类重新中定义了基类中同名的函数(非虚函数和静态函数)此时基类中的同名函数被隐藏

重载:在同一个作用域内我们定义了几个同名函数他们通过参数列表来区分彼此称为重载


*我们可以在支持C++11的编译器中给覆盖加上override关键字,那么我们在编写该函数时编译器会检查   它形式的正确性,保证我们的调试变得更加简单


本文出自 “Zimomo” 博客,请务必保留此出处http://zimomo.blog.51cto.com/10799874/1752936

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C++重点复习题(多态和继承).doc

  • 2014年04月10日 13:34
  • 54KB
  • 下载

C++继承与多态例子

  • 2009年06月28日 17:13
  • 1.63MB
  • 下载

C++ — 继承和多态的基础虚函数类

这里的虚函数在继承和多态里有举足轻重的位置,它解决了不少继承和多态里面的问题,所以一定要深刻理解,活学活用。...
  • Dawn_sf
  • Dawn_sf
  • 2017年04月01日 11:28
  • 1102

浅谈c++的精髓之继承和多态

  • 2016年09月10日 14:58
  • 89KB
  • 下载

C++多态与继承详解

  • 2014年06月03日 21:00
  • 438KB
  • 下载

c++多态之继承3-派生类的构造次序

上篇文章中我介绍了一些c++中继承的基本知识,本文我们将更近的观察下当派生类被实例化的时候发生的一些事。 首先,我们引用一个新的类来说明一些重要知识点。 class Base { public: ...

小白入门C++ 继承 多态 函数重载

概念:继承和多态继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写; 有了继承,才能有多态。在调用类实例方法的时候,尽量把变量视...
  • DanyHgc
  • DanyHgc
  • 2017年06月28日 13:59
  • 127

关于c++ 继承多态的深度思考

  • 2011年08月23日 21:22
  • 64KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ 继承&多态
举报原因:
原因补充:

(最多只允许输入30个字)