c++ 继承

来源:互联网 发布:手机编写c语言的软件 编辑:程序博客网 时间:2024/05/18 03:31

继承面临许多技术问题,包括父类与子类的访问权限规定,子类对象既然包含了父类对象,那么初始化和构造函数的顺序规定,子类对象与父类对象的关系,当然我们也要考虑与比较类的组合与类的继承的差异,来深刻学习继承的方法。

继承可以使已经存在的类无需修改就可适应新应用,继承是比重用规模更广的重用。

1、派生类对象结构

class BaseClass{    int a,b;public://共有成员}

派生类继承的方式是在类定义的class类名的后面加上:”public”,再加上基类名。

class B:public BaseClass{    int c;public:    //公有成员}

派生类对象本体包括两个部分,一个是基类部分(即含有两个整形空间),另一个是派生类部分(即含有一个整形空间)。

2、继承父类成员
protected保护成员和私有成员一样不能被使用类的程序进行公共访问,但可以被类内的成员函数访问,如果使用的类是派生类成员,则可以被访问,这是私有成员不具有的能力。

派生类的无参构造函数会首先调用父类的无参构造函数,如果父类定义了有参构造函数(因此没有默认无参构造函数),有没有重载定义无参构造函数,则会导致编译出问题。也并不是一定要调用默认无参构造函数的,而是可以在派生类的构造函数中规定调用基类构造函数的形式。

析构函数的执行顺序是与构造函数的顺序严格相反的。
构造函数失败时的解决办法时异常捕获。

3、继承方式
继承可以公有继承、保护继承和私有继承。对于不同的继承方式,其访问控制的约束是不同的。

基类的私有成员在派生类采用任何方式下都是隔离的,也就是视派生为外人,必须通过基类的保护或共有函数去访问他们。

这里写图片描述

4、继承与组合
类含有对象成员的情形称为组合。继承和组合包含对象的方式不同:一个是继承式包含一个是组合式包含。

对于组合,成员对象的数据隐私是不能被直接访问的,必须通过成员对象的操作去间接访问。
对于继承,由于派生类与基类性质的一致性,所以可以从基类的访问控制中获得对基类对象的数据成员直接访问的便利。

继承和组合并不是绝对的,组合完全可以用继承来实现,继承也可以由组合来实现,无非在继承中可以通过调整成员的访问控制属性,以达到刚编程的目的。

5、多继承概念
一个类可以从多个基类派生,这样的继承结构称为多重继承。

class SleepSofa:public Bed,public Sofa{    //code}

多继承时发生基类成员名冲突的情况时:为了明确访问目的,必须在冲突成员名前加前缀以说明基类

6、虚拟继承
虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下:

class A

class B1:public virtual A;

class B2:public virtual A;

class D:public B1,public B2;

虚拟继承在一般的应用中很少用到,所以也往往被忽视,这也主要是因为在C++中,多重继承是不推荐的,也并不常用,而一旦离开了多重继承,虚拟继承就完全失去了存在的必要因为这样只会降低效率和占用更多的空间。

第一种情况:         第二种情况:          第三种情况            第四种情况:
class a           class a             class a              class a
{              {                {                 {
virtual void func();      virtual void func();       virtual void func();        virtual void func();
};              };                  char x;              char x;
class b:public virtual a   class b :public a        };                };
{              {                class b:public virtual a      class b:public a
virtual void foo();       virtual void foo();     {                 {
};              };                  virtual void foo();        virtual void foo();
                               };                };

如果对这四种情况分别求sizeof(a), sizeof(b)。结果是什么样的呢?下面是输出结果:(在vc6.0中运行)
第一种:4,12
第二种:4,4
第三种:8,16
第四种:8,8

想想这是为什么呢?

因为每个存在虚函数的类都要有一个4字节的指针指向自己的虚函数表,所以每种情况的类a所占的字节数应该是没有什么问题的,那么类b的字节数怎么算呢?看“第一种”和“第三种”情况采用的是虚继承,那么这时候就要有这样的一个指针vptr_b_a,这个指针叫虚类指针,也是四个字节;还要包括类a的字节数,所以类b的字节数就求出来了。而“第二种”和“第四种”情况则不包括vptr_b_a这个指针,这回应该木有问题了吧。

1 0
原创粉丝点击