资源预览内容
第1页 / 共33页
第2页 / 共33页
第3页 / 共33页
第4页 / 共33页
第5页 / 共33页
第6页 / 共33页
第7页 / 共33页
第8页 / 共33页
第9页 / 共33页
第10页 / 共33页
亲,该文档总共33页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
概念问题概念问题 C C+/ /数据结构数据结构 1、 简述你对“面向对象”和“面向过程”编程思想的认识与思考 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。 例如五子棋,面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤 2,9、输出最后结果。把上面每个步骤用分别的函数来实现,问题就解决了。 而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为 1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的 i 变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。 可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了总多步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。 功能上的统一保证了面向对象设计的可扩展性。比如我要加入悔棋的功能,如果要改动面向过程的设计,那么从输入到判断到显示这一连串的步骤都要改动,甚至步骤之间的循序都要进行大规模调整。如果是面向对象的话,只用改动棋盘对象就行了,棋盘系统保存了黑白双方的棋谱,简单回溯就可以了,而显示和规则判断则不用顾及,同时整个对对象功能的调用顺序都没有变化,改动只是局部的。 再比如我要把这个五子棋游戏改为围棋游戏,如果你是面向过程设计,那么五子棋的规则就分布在了你的程序的每一个角落,要改动还不如重写。但是如果你当初就是面向对象的设计,那么你只用改动规则对象就可以了,五子棋和围棋的区别不就是规则吗?(当然棋盘大小好像也不一样,但是你会觉得这是一个难题吗?直接在棋盘对象中进行一番小改动就可以了。)而下棋的大致步骤从面向对象的角度来看没有任何变化。 当然,要达到改动只是局部的需要设计的人有足够的经验,使用对象不能保证你的程序就是面向对象,初学者或者很蹩脚的程序员很可能以面向对象之虚而行面向过程之实,这样设计出来的所谓面向对象的程序很难有良好的可移植性和可扩展性。 2、 ADT 是什么?简述你对“数据抽象”和“信息隐藏”的认识 抽象数据类型(Abstract Data Type 简称 ADT)是指一个数学模型以及定义在此数学模型上的一组操作。抽象数据类型需要通过固有数据类型(高级编程语言中已实现的数据类型)来实现。抽象数据类型是与表示无关的数据类型抽象数据类型是与表示无关的数据类型,是一个数据模型及定义在该模型上的一组运算。对一个抽象数据类型进行定义时,必须给出它的名字及各运算的运算符名,即函数名,并且规定这些函数的参数性质。一旦定义了一个抽象数据类型及具体实现,程序设计中就可以像使用基本数据类型那样,十分方便地使用抽象数据类型。 抽象数据类型通过类(class)实现 程序设计语言对抽象数据类型的支持是指允许用户自定义具有如下特征的数据类型: 1. 模块封装:The representation of, and operations on, objects of the type are defined in a single syntactic unit 2. 信息隐蔽:The representation of objects of the type is hidden from the program units that use these objects, so the only operations possible are those provided in the types definition 3、const 和 static 有什么作用? const 是一个 C 和 C+语言的关键字,它限定一个变量不允许被改变,即只读。使用 const 在一定程度上可以提高程序的安全性和可靠性,也便于实现对此进行优化(如把只读对象放入 ROM 中) 。const作为类型限定符,是类型的一部分。 静态变量静态变量(Static Variable)在计算机编程领域指在程序执行前系统就为之静态分配(也即在运行时中不再改变分配情况)存储空间的一类变量。与之相对应的是在运行时只暂时存在的自动变量(即局部变量)与以动态分配方式获取存储空间的一些对象,其中自动变量的存储空间在调用栈上分配与释放。 初始化为非零值的静态分配数据和全局数据存在数据段中,运行相同程序的每个进程都有自己的数据段。 初始化为零值的静态分配数据和全局数据存放在进程的 BSS 区域内。 BSS 段:段:BSS 段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS 是英文Block Started by Symbol 的简称。BSS 段属于静态内存分配。 是“Block Started bySymbol”的缩写,意为“以符号开始的块”。 BSS 是 Unix 链接器产生的未初始化数据段。其他的段分别是包含程序代码的“text”段和包含已初始化数据的“data”段。BSS 段的变量只有名称和大小却没有值。此名后来被许多文件格式使用,包括 PE。“以符号开始的块”指的是编译器处理未初始化数据的地方。BSS 节不包含任何数据,只是简单的维护开始和结束的地址,以便内存区能在运行时被有效地清零。BSS 节在应用程序的二进制映象文件中并不存在。 数据段:数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。静态变量静态变量存放在 data 段中 代码段:代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。代码段是存放了程序代码的数据,假如机器代码段是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用同一个代码段。中有数个进程运行相同的一个程序,那么它们就可以使用同一个代码段。 堆(堆(heap):堆是用于存放进程运行中被动态分配的内存段动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用 malloc 等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用 free 等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减) 栈栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量局部变量,也就是说我们函数括弧“”中定义的变量(但不包括 static 声明的变量,static 意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。 4、友元关系的利与弊 如果将一个函数或一个类声明为另一个类的友元,那么它就可以直接存取这个类对象中的各种数据,而不必在意这些数据的封装级别,即无论是 private 的,protected 的,还是 public 的,有钱同使,有难同当。 关于友元利弊的分析: 面向对象程序设计的一个基本原则是封装性和信息隐蔽,而友元却可以访问其他类中的私面向对象程序设计的一个基本原则是封装性和信息隐蔽,而友元却可以访问其他类中的私有成员, 不能不说这是对封装原则的一个小的破坏有成员, 不能不说这是对封装原则的一个小的破坏。 但是它能有助于数据共享, 能提高程序的效率, 在使用友元时,要注意到它的副作用,不要过多地使用友元,只有在使用它能使程序精炼,并能大大提高程序的效率时才用友元。 为什么有些操作符重载()必须要用友元函数而不能用成员函数? 如果是重载双目操作符(即为类的成员函数) ,就只要设置一个参数作为右侧运算量,而左侧运算量就是对象本身。 。 。 。 。 。 而 或breathe()时,根据虚表中的函数地址找到的就是 fish 类的 breathe()函数。 那么虚表指针在什么时候,或者说在什么地方初始化呢? 答案是在构造函数中进行虚表的创建和虚表指针的初始化。还记得构造函数的调用顺序吗,在构造子类对象时,要先调用父类的构造函数,此时编译器只“看到了”父类,并不知道后面是否后还有继承者,它初始化父类对象的虚表指针,该虚表指针指向父类的虚表。当执行子类的构造函数时,子类对象的虚表指针被初始化,指向自身的虚表。对于例 2-2 的程序来说,当 fish 类的 fh 对象构造完毕后,其内部的虚表指针也就被初始化为指向 fish 类的虚表。在类型转换后,调用 pAn-breathe(),由于 pAn 实际指向的是 fish 类的对象,该对象内部的虚表指针指向的是 fish 类的虚表,因此最终调用的是 fish 类的 breathe()函数。 要注意:对于虚函数调用来说,每一个对象内部都有一个虚表指针,该虚表指针被初始化为本类的虚表。所以在程序中,不管你的对象类型如何转换,但该对象内部的虚表指针是固定的,所以呢,才能实现动态的对象函数调用,这就是 C+多态性实现的原理。 6、STL 是什么?组成部分和核心作用 标准模板库标准模板库(英文:Standard Template Library,缩写:STL),是一个 C+软件库,也是 C+标准程序库的一部分。其中包含 5 个组件,分别为算法、容器、迭代器、函数、适配器。容器即物之所属;算法是解决问题的方式;迭代器是对容器的访问逻辑的抽象,是连接算法和容器的纽带,通过添加了一种间接层的方式实现了容器和算法之间的独立。本文从应用的角度对 STL 的方方面面进行了简单的介绍。 模板是 C+程序设计语言中的一个重要特征,而标准模板库正是基于此特征。标准模板库使得 C+编程语言在有了同 Java 一样强大的类库的同时,保有了更大的可扩展性。 标准模板库于 1994 年 2 月年正式成为 ANSI/ISO C+的一部份,它的出现,促使 C+程序员的思维方式更朝向泛型编泛型编程(程(generic program)发展。 7、阐述C+在什么情况下必须进行运算符重载。 ? 8、 为什么说“继承是C+面向对象的一个主要特征之一”,请做一下简要说明。 ? 9、 请说明函数模板(Function Template)和函数模板实例化(function-template specification)的区别和联系。 函数模板实例化 在函数模板为每个类型时首先调用中,编译器创建一个实例化。 每个实例化是为该类型的该模板化功能的版本。 在中,此函数为类型时,使用此实例化将调用。 如果您有几个相同的实例化,即使在不同的模块,因此,只有该实例化的一个副本在可执行文件将结果。 函数参数将所有参数的函数模板允许和参数,对该参数不依赖于模板参数的位置。 函数模板可以通过声明与特定类型的模板显式实例化作为参数。 C+中提供了函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表,这个通用函数就成为函数模板。使用模板的好处就是对于那些函数体相同的函数都可以用这个模板来代替,而不必去定义每个具体的函数去实现。下面通过一个简单的具体例子(比较两个数的大小)来说明: #include using namespace std; template /模
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号