`

面向对象的设计(4)

阅读更多
<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

对于一个非虚拟函数的调用,编译器在编译时刻选择被调用的函数,而虚拟函数调用的

决定则要等到运行时刻。在执行程序内部的每个调用点上,系统根据被调用对象的实际基类

或派生类的类型来决定选择哪一个虚拟函数。实例,例如考虑下面的代码

void init( IntArray &ia )

{

for ( int ix = 0; ix < ia.size(); ++ix )

ia[ ix ] = ix;

}

形式参数ia 可以引用IntSortedArray、IntArrayRC 或IntArray 类的对象。我们将简要介

绍这里的派生类函数,size()作为非虚拟函数由编译器处理并内联展开,但是下标操

作符要直到执行循环的每次迭代时才能被处理,因为在编译期间编译器不知道数组ia 指向的

实际类型。

第17 章将详细讨论虚拟函数,包括虚拟析构函数的主题以及使用虚拟函数设计带来

的效率问题,【LIPPMAN96a 】对虚拟函数的实现与效率有更深入的讨论。

一旦我们定好了设计方案,C++的实现就很容易了。例如下面这个完整的IntArrayRC

派生类定义被放在一个独立的头文件IntArrayRC.h 中,该文件包含头文件IntArray.h, 而

IntArray.h 包含有IntArray 类的定义。

#ifndef IntArrayRC_H

#define IntArrayRC_H

#include "IntArray.h"

class IntArrayRC : public IntArray {

public:

IntArrayRC( int sz = DefaultArraySize );

IntArrayRC( int *array, int array_size );

IntArrayRC( const IntArrayRC &rhs );

virtual int& operator[]( int );

private:

void check_range( int );

};

#endif

IntArrayRC 只需定义不同于IntArray 实现的那些方面,或者加上对IntArray 扩展的实现。

1 它必须提供自己的下标操作符实例,以支持范围检查

2 它必须提供一个操作来做实际的检查工作,由于它不是公有接口的一部分,所以我们

把它声明为private

3 它必须提供一组自动初始化函数,即自己的构造函数集。

IntArray 的成员函数与数据成员对于IntArrayRC 来说都是可用的,就如同IntArrayRC

已经显式地定义了它们一样。这正是下面这句话的含义

class IntArrayRC : public IntArray

冒号定义了IntArrayRC 是从IntArray 派生而来的。关键字public 表明派生类共享基类

的公有接口。IntArrayRC 类型的对象可以用在任何可以使用基类类型对象的位置上。比

如在swap()例子中。第18 章会详细解释这一点。IntArrayRC 可以看作是IntArray 的扩展。

它增加了下标范围检查的额外特性。下面是下标操作符的一个实现

inline int&

IntArrayRC::operator[]( int index )

{

check_range( index );

return ia[ index ];

}

这里check_range()被实现为一个内联成员函数,它调用assert()宏。关于assert()宏的讨

论见1.3 节

#include <cassert>

inline void

IntArrayRC::check_range( int index )

{

assert( index >= 0 && index < size );

}

我们把check_range()函数作为一个独立的函数,以便说明私有成员函数并且将范围检

查的处理封装起来,方便我们以后改变边界错误的处理方式或是用异常处理代替assert()。

派生类对象实际上由几部分构成,每个基类是一个类的子对象subobject,它在新定

义的派生类中有独立的一部分派生类。对象的初始化过程是这样的:首先自动调用每个基类的构造函数来初始化相关的基类子对象,然后再执行派生类的构造函数。从设计的角度来看,派生类的构造函数应该只初始化那些在派生类中被定义的数据成员,而不是基类中的数据成员。

虽然我们引入了与类相关的下标操作符版本,以及一个私有的check_range()辅助函数,

但是我们并没有引入需要初始化的额外数据成员,因此,我们可以合理地假设.继承基类的

构造函数已经足够了,我们不需要再提供IntArrayRC 的构造函数——因为不需要它们做任何事情。

但是,实际上我们还是需要提供IntArrayRC 的构造函数,因为基类的构造函数并没有

被派生类继承,析构函数和拷贝赋值操作符同样也没有,还因为我们需要某个接口以便

通过这个接口把必要的参数传递给基类IntArray 的构造函数。

例如,假设我们定义了一个IntArrayRC 对象

int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13 };IntArrayRC iarc( ia, 8 );

怎样才能把ia 和8 传递给基类的构造函数呢?不可否认,如果IntArray 构造函数被继承

了,那么就没有这个问题。实际上,那样的话我们会有其他更严重的问题,但现在没有足够的

篇幅向你证明这一点,无论如何派生类构造函数的语法提供了向基类构造函数传递参数的

接口。

例如,下面是两个必需的IntArrayRC 构造函数,第14 章与第17 章将对构造函数作更

多的讲解。其中,包括关于为什么我们不需要提供IntArrayRC 拷贝构造函数的解释

inline IntArrayRC::IntArrayRC( int sz)

: IntArray( sz ) {}

inline IntArrayRC::IntArrayRC( const int *iar, int sz )

: IntArray( iar, sz ) {}

由冒号分割出来的部分称作成员初始化列表member initialization list,它提供了一种

机制,通过这种机制,我们可以向IntArray 的构造函数传递参数。两个IntArrayRC 构造函数

的函数体都是空的,因为它们的工作就是把参数传递给相关的IntArray 构造函数,我们无需

提供显式的IntArrayRC 析构函数,因为派生类没有引入任何需要析构的数据成员,继承过来

的需要析构的IntArray 成员都由IntArray 的析构函数来处理。

分享到:
评论

相关推荐

    面向对象概要设计模板

    面向对象设计是一种软件设计方法,它强调对象之间的交互和协作,以达到软件系统的高内聚、低耦合的目标。在软件设计中,面向对象设计方法可以帮助开发者更好地理解系统的需求和行为,从而提高软件系统的质量和可维护...

    UML面向对象设计基础

    ### UML面向对象设计基础 #### 基本概念与符号表示 《UML面向对象设计基础》一书详细介绍了面向对象软件设计的基础知识,包括基本概念、符号表示、术语、准则和原理。面向对象设计是一种软件设计范式,强调通过对象...

    面向对象设计UML实践课后答案

    面向对象设计(Object-Oriented Design,OOD)是一种软件开发方法,它基于“对象”的概念,将现实世界的问题域转化为计算机程序。UML(Unified Modeling Language)是面向对象设计的一种标准化建模语言,用于可视化...

    面向对象设计理论

    面向对象设计理论是软件开发领域中的核心概念,它是一种基于现实世界中对象和它们之间交互的编程模型。这种设计方法论极大地提高了代码的可维护性、可扩展性和重用性。下面将详细阐述面向对象设计的基本概念、原则...

    23种面向对象设计模式

    面向对象设计模式是软件开发中的一种重要思想,它通过总结和提炼在软件设计过程中常见的问题和解决方案,形成了可复用的设计规范。标题提到的“23种面向对象设计模式”涵盖了设计模式的主要分类,这些模式在Java、...

    面向对象程序设计—图书管理系统设计.pdf

    "面向对象程序设计—图书管理系统设计" 面向对象程序设计是当前软件开发的主流技术之一,其应用范围非常广泛,涵盖了各个行业和领域。图书管理系统是图书馆中的一种重要管理系统,它负责管理图书的存储、借阅、归还...

    面向对象分析与设计.pdf

    面向对象设计是在分析的基础上进行的,它关注于如何将需求转化为软件系统的内部结构。设计阶段的输出通常包括更详细的类图、活动图、序列图、状态图和组件图等UML模型。设计过程还会确定系统组件的接口和协作方式。 ...

    面向对象设计原理与模式(Java版)

    《面向对象设计原理与模式(Java版)》全面介绍了Java面向对象程序设计的原理和模式,帮助解决Java程序中的设计问题。此外,该书十分注重Java面向对象程序设计的每个细节,以及继承、方法、类、设计模式等在程序设计...

    面向对象系统分析与设计.pdf

    4. 继承:继承是面向对象设计中的一个核心机制,它允许创建一个新类来继承现有类的属性和方法。这使得软件设计可以复用和扩展。 5. UML(统一建模语言):UML是一种标准的图形化建模语言,用于软件系统的设计和文档...

    面向对象程序设计 c++面向对象程序设计 c++面向对象程序设计PPT课件

    面向对象程序设计 c++面向对象程序设计 c++面向对象程序设计

    面向对象程序设计—C++语言描述PDF

    《面向对象程序设计:C++语言描述(原书第2版)》内容丰富,结构合理,写作风格严谨,深刻地论述了c++语言的面向对象编程的各种技术,主要内容包括:面向对象编程方法、c++语言的各种特性、stl、c++输入/输出流、mfc等。...

    面向对象设计之3_基于UML的图书管理系统的分析与设计说明.pdf

    面向对象设计之3_基于UML的图书管理系统的分析与设计说明 本资源摘要信息主要介绍面向对象设计和UML(Unified Modeling Language)在图书管理系统中的应用。面向对象设计是一种程序设计方法,强调使用对象、类、...

    C#面向对象设计模式纵横谈(1):面向对象设计模式与原则

    面向对象设计模式是软件开发中的重要工具,它们是经过时间考验和广泛实践验证的设计解决方案,旨在提高代码的可重用性、灵活性和可维护性。C#作为一款强大的面向对象编程语言,为开发者提供了实现这些设计模式的良好...

    C#面向对象设计模式纵横谈(视频与源码)

    C#面向对象设计模式纵横谈(4):Builder 生成器模式(创建型模式) C#面向对象设计模式纵横谈(5):Factory Method 工厂方法模式(创建型模式) C#面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式) C#面向...

    面向对象程序设计课程设计题目

    面向对象程序设计课程设计题目 面向对象程序设计课程设计是一门旨在提高学生实际分析问题、编程和动手能力的课程设计。课程设计旨在引导学生学习掌握面向对象思想和 Java 编程语言,熟练运用 Java 工具,通过课程...

    面向对象分析与设计UML2.0(PDF)

    详细介绍了面向对象的分析与设计,全面探讨了面向对象概念、软件开发过程、UML和多层技术。本书使用最常见的技术和方法,通过一个贯穿全书的案例分析,对面向对象的软件开发过程和使用面向对象技术的编程过程进行了...

Global site tag (gtag.js) - Google Analytics