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++继承//多态

这几天着重研究呃C++的继承和多态两个重要章节; 通过一个题,不断的优化达到理解的效果,继承的重点在于三种继承方式的区别 public private protected public继承:基类...

[c++]继承 多态

继承: 是除了基类的构造函数 ,析构函数 全部继承(私有 也可继承 但不可直接访问)继承方法:public: is-a关系 base private 不可访问 public p...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

c++多继承多态

C++多继承多态的实现如果一个类中存在虚函数,在声明类的对象时,编译器就会给该对象生成一个虚函数指针,该虚函数指针指向该类对应的虚函数表。 多态的实现是因为使用了一种动态绑定的机制,在编译期间不确定...

【C#】C#继承与多态

继承与多态 一、继承    1、语法 如何调用? 举例:动物类  2、调用基类的成员      3、base关键字    调用base构...

继承&多态

继承&多态 虚继承 虚函数
  • MJ813
  • MJ813
  • 2015-09-13 15:20
  • 117

继承、多态

继承(inheritance)        简单的说,继承就是在一个现有类型的基础上,通过增加新的方法或者重定义已有方法(下面会讲到,这种方式叫重写)的方式,产生一个新的类型。继承是面向对象的...

C++继承和多态

一、继承 C++继承的3种关系 1、public继承       public继承是一种接口继承,子类可以代替父类完成接口所声明的行为。此时,子类可以自动转换成父类的接口,完成接口的转换。 从语法的...

C++之继承与多态

C++之继承与多态 在程序设计领域,一个广泛认可的定义是“一种将不同的特殊行为和单个泛化记号相关联的能力”。和纯粹的面向对象程序设计语言不同,C++中的多态有着更广泛的含义。除了...

C#(二) -继承与多态

咱们书接上回(抽象类与接口)。    学了这么多天,包括C#的初步理解和大话设计模式的终结,越来越能感受到OO的魅力所在了。    都说编程源自生活,就是说程序设计大神们从吃饭睡觉打豆豆等一系列日...

c++继承与多态

C++ 继承与多态
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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