Chinaunix首页 | 论坛 | 博客
  • 博客访问: 254283
  • 博文数量: 78
  • 博客积分: 1465
  • 博客等级: 上尉
  • 技术积分: 972
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-28 13:46
文章分类

全部博文(78)

文章存档

2012年(1)

2011年(9)

2010年(68)

我的朋友

分类: C/C++

2010-01-13 00:35:52

平时没怎么用C++写程序做项目,现在为了找工作不得不补习C++的基础理论知识。关于C++的类的继承与重载我一直没太弄明白,从网上搜了一篇关于继承的文章,觉得讲的非常清楚,所以转来共享了。

原文地址:http://lz881228.blog.163.com/blog/static/11419732420095351744781/

通过继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。我们称已存在的用来派生新类的类为基类,又称为父类。由已存在的类派生出的新类称为派生类,又称为子类。

  在C++语言中,一个派生类可以从一个基类派生,也可以从多个基类派生。从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。

  派生类的定义格式

  单继承的定义格式如下:

  class <派生类名>:<继承方式><基类名>

  {

  <派生类新定义成员>

  };

  其中,<派生类名>是新定义的一个类的名字,它是从<基类名>中派生的,并且按指定的<继承方式>派生的。<继承方式>常使用如下三种关键字给予表示:

  public 表示公有基类;

  private 表示私有基类;

  protected 表示保护基类;

  多继承的定义格式如下:

  class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…

  {

  <派生类新定义成员>

  };

  可见,多继承与单继承的区别从定义格式上看,主要是多继承的基类多于一个。

  派生类的三种继承方式

  公有继承(public)、私有继承(private)、保护继承(protected)是常用的三种继承方式。

  1. 公有继承(public)

  公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的。

  2. 私有继承(private)

  私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。

  3. 保护继承(protected)

  保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。

  下面列出三种不同的继承方式的基类特性和派生类特性。

  不同继承方式的基类和派生类特性

  继承方式基类特性派生类特性 公有继承 public public protected

  private protected

  不可访问

  私有继承 public private protected

  private private

  不可访问

  保护继承 public protected protected

  private protected

  不可访问

  为了进一步理解三种不同的继承方式在其成员的可见性方面的区别,下面从三种不同角度进行讨论。

  对于公有继承方式:

  (1) 基类成员对其对象的可见性

  公有成员可见,其他不可见。这里保护成员同于私有成员。

  (2) 基类成员对派生类的可见性:

  公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员。

  (3) 基类成员对派生类对象的可见性:

  公有成员可见,其他成员不可见

  所以,在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。这里,一定要区分清楚派生类的对象和派生类中的成员函数对基类的访问是不同的。

  对于私有继承方式:

  (1) 基类成员对其对象的可见性:

  公有成员可见,其他成员不可见。

  (2) 基类成员对派生类的可见性:

  公有成员和保护成员是可见的,而私有成员是不可见的。

  (3) 基类成员对派生类对象的可见性:

  所有成员都是不可见的。

  所以,在私有继承时,基类的成员只能由直接派生类访问,而无法再往下继承。

  对于保护继承方式:

  这种继承方式与私有继承方式的情况相同。两者的区别仅在于对派生类的成员而言,对基类成员有不同的可见性。

  上述所说的可见性也就是可访问性。关于可访问性还有另的一种说法。这种规则中,称派生类的对象对基类访问为水平访问,称派生类的派生类对基类的访问为垂直访问。

  一般规则如下:

  公有继承时,水平访问和垂直访问对基类中的公有成员不受限制;

  私有继承时,水平访问和垂直访问对基类中的公有成员都不能访问;

  保护继承时,对于垂直访问同于公有继承,对于水平访问同于私有继承。

  对于基类中的私有成员,只能被基类中的成员函数和友元函数所访问,不能被其他的函数访问。

  基类与派生类的关系

  任何一个类都可以派生出一个新类,派生类也可以再派生出新类,因此,基类和派生类是相对而言的。

  基类与派生类之间的关系可以有如下几种描述:

  1. 派生类是基类的具体化

  类的层次通常反映了客观世界中某种真实的模型。在这种情况下,不难看出:基类是对若干个派生类的抽象,而派生类是基类的具体化。基类抽取了它的派生类的公共特征,而派生类通过增加行为将抽象类变为某种有用的类型。

  2. 派生类是基类定义的延续

  先定义一个抽象基类,该基类中有些操作并未实现。然后定义非抽象的派生类,实现抽象基类中定义的操作。例如,虚函数就属此类情况。这时,派生类是抽象的基类的实现,即可看成是基类定义的延续。这也是派生类的一种常用方法。

  3. 派生类是基类的组合

  在多继承时,一个派生类有多于一个的基类,这时派生类将是所有基类行为的组合。

  派生类将其本身与基类区别开来的方法是添加数据成员和成员函数。因此,继承的机制将使得在创建新类时,只需说明新类与已有类的区别,从而大量原有的程序代码都可以复用,所以有人称类是“可复用的软件构件”。

 
* 如果没有提供访问说明符,编译器就假定访问是私有的,除非基类是一个结构(这时,编译器假定访问是公有的)。
* 除非基类有默认的构造函数(即不带参数的构造函数),否则必须提供基类的参数初始化表。
* 类机制的特性罗列清单:
       1. 公有(public)继承父类各成员保持原有属性传递给子类;私有(privated)类继承父类可继承成员及函数都成为子类私有对象。
 
       2. 子类通过::(域访问控制符)访问父类资源。
 
       3. 从同一个父类继承的任意多个子类之间没有任何关系。
 
       4. 在类中需要常量数据时,可以用enum定义。
 
       5.虚函数如不在子类中改写则沿用父类特性;纯虚函数如不在子类中改写则子类也无法实例化。
 
       6. 虚函数的设置可以让指针性变量正确使用函数;基类析构函数应该都设置成虚函数以方便类对象的回收。
 
       7. 子类继承了父类的所有公用成员和保护成员(成员函数不占空间),同时还加了一张虚拟函数表(virtual table)。
 
       8. 多重继承时父类构造函数的执行顺序取决与子类中申明父类的顺序;如果类定义中包含另一个类的对象,则构造函数的执行情况是父类先执行,然后是包含对象类构造函数,最后才是子类本身。

例子:class Son : public father1, public father2
     {
         otherClass  otherClassdata;

          .................

          .................
     };

构造函数执行顺序: father1,father2,otherClass,Son
析构函数执行顺序: Son,otherClass, father2,father1

       9. 构造函数带参数的类不能是虚基类;指向虚基类的指针不能被强制转换成类层次结构中该类下的类型(类层次结构中某个虚基类的出现只共享一次)。

(以下来自:http://morningsun.blogbus.com/logs/522762.html

public继承中,可以把一个派生类的对象作为它的基类对象来进行处理,另外,也可以把一个基类对象的指针强制转换成派生类指针,不过,必须首先确保它一定是指向某个派生类对象的;如果把指向基类对象的指针显式的转换成派生类指针以后,引用该对象中并不存在的派生类的成员会导致运行时的逻辑错误。

由于派生类继承了基类的成员,所以在建立派生类的实例对象时,必须调用基类的构造函数来初始化派生类对象的基类成员。派生类的构造函数既可以隐式的调用基类的构造函数,也可以在派生类的构造函数通过给基类提供初始化值显式的调用基类的构造函数。派生类不继承基类的构造函数和赋值运算符,但是派生类构造函数和赋值运算符能够调用基类的构造函数和赋值运算符。派生类的构造函数总是先调用其基类构造函数来初始化派生类中的基类成员。如果省略了派生类的构造函数,那么就由派生类的默认构造函数调用基类的默认构造函数。析构函数的调用顺序和构造函数的调用顺序是相反的,因此派生类的析构函数在基类的析构函数之前调用。

public继承中,因为派生类对象也是基类对象,所以指向派生类对象的指针可以隐式的转换为指向基类对象的指针。基类指针和派生类指针与基类对象和派生类对象的混合和匹配有如下4种可能的方式:

1、  直接用基类指针引用基类的对象。

2、  直接用派生类指针引用派生类对象。

3、  用基类指针引用一个派生类对象。由于派生类的对象也是基类的对象,所以这种引用方式是安全的,但是用这种方法只能引用基类成员,如果试图通过基类指针引用那些只有在派生类中才有的成员,语法错误。

4、  用派生类的指针引用基类的对象。这种引用方式会导致语法错误。派生类指针必须先强制转换为基类指针。

多重继承,意味着一个派生类可以继承多个基类的成员。

阅读(631) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~