收藏 分享(赏)

课后答案——C++语言程序设计教程(第二版).doc

上传人:kpmy5893 文档编号:7088018 上传时间:2019-05-05 格式:DOC 页数:23 大小:87.43KB
下载 相关 举报
课后答案——C++语言程序设计教程(第二版).doc_第1页
第1页 / 共23页
课后答案——C++语言程序设计教程(第二版).doc_第2页
第2页 / 共23页
课后答案——C++语言程序设计教程(第二版).doc_第3页
第3页 / 共23页
课后答案——C++语言程序设计教程(第二版).doc_第4页
第4页 / 共23页
课后答案——C++语言程序设计教程(第二版).doc_第5页
第5页 / 共23页
点击查看更多>>
资源描述

1、1.1 习题 1 解答1.(1)机器语言是计算机直接理解执行的语言,由一系列(二进制)指令组成,其助记符构成了汇编语言;接近人的自然语言习惯的程序设计语言为高级语言。(2)结构化程序设计方法主要内容有:自顶向下,逐步求精;面向对象方法将现实世界中的客观事物描述成具有属性和行为的对象,抽象出共同属性和行为,形成类。(3)C+ 程序开发通常要经过 5 个阶段,包括:编辑,编译,连接,运行,调试。首先是编辑阶段,任务是编辑源程序,C+源程序文件通常带有 .c p p 扩展名。接着,使用编译器对源程序进行编译,将源程序翻译为机器语言代码(目标代码) ,过程分为词法分析、语法分析、代码生成 3 个步骤。

2、在此之前,预编译器会自动执行源程序中的预处理指令,完成将其他源程序文件包括到要编译的文件中,以及执行各种文字替换等。连接器的功能就是将目标代码同缺失函数的代码连接起来,将这个“漏洞”补上,生成可执行文件。程序运行时,可执行文件由操作系统装入内存,然后 CPU 从内存中取出程序执行。若程序运行进程中出现了错误,还在需要对程序进行调试。(4)对象与对象之间通过消息进行相互通信。(5)类是具有相同属性和行为的一组对象的抽象;任何一个对象都是某个类的一个实例。(6)多态性是指在一般类中定义的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。(7)面向对象的软件开发过程主要包括面向

3、对象的方法分析、面向对象的设计、面向对象的编程、面向对象的测试和面向对象的维护。(8)泛型程序设计是指在程序设计时,将数据类型参数化,编写具有通用性和可重用的程序。(9)# include 是一条预处理指令(语句) ,在编译(或预处理)时由编译器(或预编译器)执行,其功能是将 iostream 文件包含(复制)到指令处。(10)C+中使用 cin 作为标准输入流对象,通常代表键盘,与提取操作符连用;使用cout 作为标准 输出流对象,通常代表显示设备,与运算符将一个数右移 n 位,相当于将该数除以 2n,(11)若 fun(8,3.1)调用的可以是 fun(double, double)(当没

4、有精确匹配时,优先进行向高类型转换后的匹配)(12)若 fun(8,3.1)调用的可以是 template fun (T1,T2)1.5 习题解答1.(1)enum weekday sun,mon,tue,wed=4,thu,fri,sat;weekday workday =mon;cout 。(15)析构函数在对象的生存期结束时被自动调用,全局对象和静态对象的析构函数在程序运行结束时调用。(16)设 p 是指向一个类的动态对象的指针变量,则执行 delete P;语句时,将自动调用该类的析构函数。2.(1)数据封装就是将一组数据和与这组数据有关操作组装在一起,形成一个实体,这实体也就是类。(

5、2)类的实例化就是创建类的对象。(3)已知 p 是一个指向类 Sample 数据成员 m 的指针,s 是类Sample 的一个对象。如果要给 m 赋值为:s.*p=5; (4)类与对象的关系和数据类型与变量的关系是相似的,对象是类的一个实例,一个对象只能属于一个具体的类。(5)封装要求对象就具有明确的功能,它使得一个对象可以像一个部件一样用在各种程序中。封装是将一组数据和这组数据有关的操作组装在一起。(6)内联函数是在编译时(而不是运行时)将该函数的目标代码插入到每一个调用该函数的地方。(7)类中的函数成员可以在类体中定义,也可以在类体之外定义。(8)+中的对象并不是语言中的结构体变量 ,它是

6、一个状态和操作(或方法)的封装体,对象代表着正在创建的系统中的一个实体,对象之间的信息传递是通过消息进行的。(9)在建立类的对象时只为每个对象分配用于保存数据成员的内存。3.(1)类和数据类型有何关联?类相当于一种包含函数的自定义数据类型,它不占内存空间,是一个抽象的“虚”体,使用已定义的类建立对象就像用数据类型定义变量一样。对象建立后,对象占据内存,变成了一个“实”体。类与对象的关系就像数据类型与变量的的关系一样。其实,一个变量就是一个简单的不含成员函数的数据对象。(2)类和对象的内存分配关系?为节省内存,编译器在创建对象时,只为各对象分配用于保存各对象数据成员初始化的值,并不为各对象的成员

7、函数分配单独的内存空间,而是共享类的成员函数定义,即类中成员函数的定义为该类的所有对象所共享,这是 C+编译器创建对象的一种方法,实际应用中,我们仍将对象理解为由数据成员和函数成员两部分组成。(3)什么是浅拷贝?什么是深拷贝?二者有何异同?构造函数用于建立对象时给对象赋初值以初始化新建立的对象。如果有一个现存的对象,在建立新对象时希望利用现存对象作为新对象的初值,即用一个已存在的对象去初始化一个新建立的对象。C+ 提供的拷贝构造函数用于在建立新对象时将已存在的对象的数据成员值复制给新,以初始化新对象。拷贝构造函数在用类的一个对象去初始化该类的另一个对象时调用,以下 3 种情况相当于用一个已存在

8、的对象去初始化新建立的对象,因此,调用拷贝构造函数: 当用类的一个对象去初始化该类的另一个对象时。 如果函数的形参是类的对象,调用函数时,将对象作为函数实参传递给函数的形参时。 如果函数的返回值是类的对象,函数执行完成,将返回值返回时。原因在于默认的拷贝构造函数实现的只能是浅拷贝,即直接将原对象的数据成员值依次复制给新对象中对应的数据成员,并没有为新对象另外分配内存资源。这样,如果对象的数据成员是指针,两个指针对象实际上指向的是同一块内存空间。当类的数据成员中有指针类型时,我们就必须定义一个特定的拷贝构造函数,该拷贝构造函数不仅可以实现原对象和新对象之间的数据成员的复制,而且可以为新的对象分配

9、单独的内存资源,这就是深拷贝构造函数。(4)什么是 this 指针? 它的作用是什么?一个类的成员函数中,有时希望引用调用它的对象,对此,C+采用隐含的 this 指针来实现。this 指针是一个系统预定义的特殊指针,指向当前对象,表示当前对象的地址。系统利用 this 指针明确指出成员函数当前操作的数据成员所属的对象。实际上,当一个对象调用其成员函数时,编译器先将该对象的地址赋给 this 指针,然后调用成员函数,这样成员函数对对象的数据成员进行操作时,就隐含使用了 this 指针。一般而言,通常不直接使用 this 指针来引用对象的成员,但在某些少数情况下,可以使用 this 指针,如重载

10、某些运算符以实现对象的连续赋值等。This 指针不是调用对象的名称,而是指向调用对象的指针的名称。This 的值不能改变,它总是指向当前调用对象。(5)C+ 中静态成员有何作用?它有何特点?C+提供了静态成员,用以解决同一个类的不同对象之间数据成员和函数的共享问题。静态成员的特点是:不管这个类创建了多少个对象,其静态成员在内存中只保留一份副本,这个副本为该类的所有对象所共享。面向对象方法中还有类属性(class attribute)的概念,类属性是描述类的所有对象的共同特征的一个数据项,对于任何对象实像实例,它的属性值是相同的,C+通过静态数据成员来实现类属性。(6)友元关联有何性质?友元关联

11、是不能传递的,不能被继承。如 B 类是 A 类的友元,C 类是 B 类的友元, C 类和 A 类之间如果没有声明,就没有任何友元关系,不能进行数据共享。友元关系是单向的,不具有交换性,如果声明 B 类是 A 类的友元,B 类的成员函数就可以访问 A 类的私有和保护数据,但 A 类的成员函数却不能访问 B 类的私有和保护数据。(7)在 C+程序设计中,友元关系的优点和缺点是什么?友元概念的引入,提高了数据的共享性,加强了函数与函数之间、类与类之间的相互联系,大大提高了程序的效率,这是友元的优点,但友元也破坏了数据隐蔽和数据封装,导致程序的可维护性变差,给程序的重用和扩充埋下了深深的隐患,这是友元

12、的缺点。(8)如何实现不同对象的内存空间的分配和释放?当类被实例化成对象后,不同类别的对象占据不同类型的内存,其规律与普通变量相同: 类的全局对象占有数据段的内存。 类的局部对象内存分配在栈中。 函数调用时为实参建立的临时对象内存分配在栈中。 使用动态内存分配语句 new 建立的动态对象,内存在堆中分配。虽然类(对象)是由数据成员与成员函数组成。但是,程序运行时,系统只为各对象的数据成员分配单独内存空间,而该类的所有对象则共享类的成员函数定义以及为成员函数分配的空间。对象的内存空间分配有下列规则: 对象的数据成员与成员函数占据不同的内存空间,数据成员的内存空间与对象的存储类别相关,成员函数的内

13、存空间在代码段中。 一个类所有对象的数据成员拥有各自的内存空间。 一个类所有对象的成员函数为该类的所有对象共享,在内存中,只有一个副本随着对象的生命周期的结束,对象所占的空间就会释放,各类对象内存空间释放时间与方法如下:a 全局对象的数据成员占有的内存空间在程序结束时释放。b 局部对象与实参对象数据成员的内存空间在函数调用结束时释放。c 动态对象数据成员的内存空间要使用 delete 语句释放。d 对象的成员函数的内存空间在该类的所有对象生命周期结束时自动释放。1.8 习题解答 1 .(1)+程序设计的关键之一是利用继承 实现软件重用,有效地缩短程序的开发时间。(2)基类的对象可以作为派生类的

14、对象使用,这称为类型兼容(或赋值兼容) 。(3)在+中, 三种派生方式的说明符号为 public, private, protected , 如果不加说明,则默认的派生方式为 private。(4)当私有派生时,基类的的公有成员成为派生类的私有成员;保护成员成为派生类的私有成员;私有成员成为派生类的不可访问成员。(5)相互关联的各个类之间的关系主要分为组成关系和继承关系。(6)在派生类中不能直接访问基类的私有成员否则破坏了基类的封装性。(7)保护成员具有双重角色,对派生类的成员函数而言,它是公有成员,但对所在类之外定义的其它函数而言则是私有成员。(8)多继承时,多个基类中的同名的成员在派生类中

15、由于标识符不唯一而出现二义性。在派生类中采用成员名限定或重定义具有二义性的成员来消除该问题。(9)+提供的多继承机制允许一个派生类继承多个基类。2.(1)一个派生类可以作为另外一个派生类的基类;派生类至少有一个基类;派生类的成员除了它自己的成员外,还包含了它的基类的成员。(2)在多继承中,公有派生和私有派生对于基类成员在派生类中的可访问性与单继承的规则是完全相同的。(3)友元关系是不能继承的。(4)派生类一般都是公有派生;对基类成员的访问必须是无二义性的;赋值兼容规则也是适用于多重继承的场合。(5)基类的保护成员在公有派生中仍然是保护的;基类的保护成员在私有派生中却是私有的;对基类成员的访问必

16、须是无二义性的。(6)在公有派生的情况下,派生类中定义的成员函数只能访问原基类中的公有成员和保护成员。(7)每个派生类的构造函数都要为虚基类构造函数提供实参;多继承时有可能出现对基类成员访问的二义性问题;建立派生类对象时,虚基类数的构造函数会首先被调用。(8)在一个派生类对象结束其生命周期时先调用基类的析构函数后调用派生类的析构函数。(9)当保护继承时,基类的公有成员和保护成员在派生类中成为保护成员,不能通过派生类的对象来直接访问。(10)若派生类的成员函数不能直接访问基类中继承来的某个成员,则该成员一定是基类中的私有成员。(11)设置虚基类的目的是消除二义性。(12)继承具有传递性,即当基类

17、本身也是某个类的派生类时,底层的派生类也会自动继承间接基类的成员。(13)在派生类构造函数的初始化列表中不能包含派生类中一般数据成员的初始化。(14)在公有派生情况下,派生类的对象可以赋给基类的对象;派生类的对象可以初始化基类的引用;派生类的对象的地址可以赋给指向基类的指针。3.(1)派生类如何实现对基类私有成员的访问?无论使用哪一种继承方式,基类的私有成员都不允许外部函数直接访问,也不允许派生的成员函数直接访问,但是可以通过基类的公有成员函数间接访问该类的私有成员。(2)什么是赋值兼容?它会带来什么问题?类型兼容是指在公有派生的情况下,一个派生类对象可以作为基类的对象来使用。类型兼容又称为类

18、型赋值值兼容或类型适应。在 C+中,类型兼容主要指以下 3 种情况: 派生类对象可以赋值给基类对象; 派生类对象可以初始化基类的引用; 派生类对象的地址可以赋给指向基类的指针;由于派生类对象中包含基类子对象,所以这种引用方式是安全的,但是这种方法只能引用从基类继承的成员。如果试图通过基类指针引用那些只有在派生类中才有的成员,编译器将会报告语法错误。(3)多重继承时,构造函数和析构函数的执行顺序是如何实现的?多得继承时,构造函数的执行顺序是:先执行基类的构造函数,再执行对象成员的构造函数,最后执行派生类的构造函数。在多个基类之间则严格按照派生类声明时从左到右的顺序来执行各基类的构造函数,而析构函

19、数的执行顺序则正好与构造函数的执行顺序相反。(4)继承与组合之间的区别和联系是什么?继承描述的是一般类与特殊类的关系,类与类之间体现的是”is a kind of”,即如果在逻辑上 A 是 B 的一种,允许 A 继承 B 的功能和属性。例如汽车(automobile)是交通工具(vehicle )的一种,小汽车( car)是汽车的一种。那么类 automobile 可以从类 vehicle 派生,类 car 可以从类 automobile 派生。组合描述的是整体与部分的关系,类与类之间体现的是”is a part of ”,如果在逻辑上 A 是 B 的一部分,则允许 A 和其他数据成员组合为

20、B。例如:发动机、车轮、电池、车门、方向盘、底盘都是小汽车的一部分,它们组合成汽车,而不能说汽车是发动机的一种。在 C+中,类的继承与类的组合很相似,继承和组合既有区别,也有联系,主要表现在描述的关系不同。某些比较复杂的类,既需要使用继承,也需要使用组合,二者一起使用。在某些情况下,继承与组合的实现还可以互换。在多继承时,一个派生类有多个直接基类,派生类实际上是所有基类属性和行为的组合。派生类是对基类的扩充,派生类的成员一部分是从基类中来,因此派生类组合了基类。既然这样,派生类也可以通过组合类实现。什么时候用继承,什么时候使用组合,要根据问题中类与类之间的具体关系,顺其自然,权衡考虑。(5)什

21、么是虚基类?它有什么作用?在多继承中,当派生类的部分或全部直接基类又是从另一个共同基类派生而来时,这些直接基类中从上一级共同基类继承来的成员就拥有相同的名称。在派生类的对象中,同名数据成员在内存中同时拥有多个副本,同一个成员函数会有多个映射,出现二义性,因此,C+将共同基类设置为虚基类。虚基类使得从不同的路径继承过来的同名数据成员在内存中只有一个副本,同一个函数也只有一个映射。这样不公解决了二义性的问题,也节省了内存,避免了数据不一致的问题。1.9 习题 9 解答1.(1)将一个函数调用链接上相应函数体的代码,这一过程称为联编(绑定) 。(2)+支持两种多态性:静态多态性和 动态多态性。(3)

22、在编译时就确定的函数调用称为静态联编,它通过使用重载函数实现。(4)在运行时才确定的函数调用称为动态联编,它通过继承和虚函数来实现。(5)虚函数的声明方法是在函数原型前加上关键字 virtual。(6)+的静态多态性是通过重载函数实现的。(7)+的动态多态性是通过虚函数实现的。(8)当通过基类指针使用虚函数时,+ 会在与对象关联的派生类中正确地选择重定义的函数。(9)如果一个类包含一个或多个纯虚函数,则该称为抽象类。(10)若以非成员函数形式,为类 Bounce 重载! 运算符,其操作结果为 bool 型数据,则该运算符重载函数的原型是:friend bool operate ! (Bounc

23、e); 2.(1)在+中:运算符不能被重载。(2)运算符重载不能改变运算数的个数、优先级、结合性和语法结构。(3)如果表达式+i*k 中的+和*都是重载的友元运算符,则采用运算符函数调用格式,该表达式还可表示为 operator*(operator+(i),k) 。(4)5.0+2.0 和 5+2 两个表达式中的 +的意义不相同。(5)有的运算符只能作为成员函数重载。(6)已知在一个类体中包含如下函数原型:VOLUME operator-(VOLUME)const;。这是运算符的重载运算符函数;这是一个成员函数;这个函数不改变类的任何数据成员的值。(7)在表达式 x+y*z 中,+ 是作为成员

24、函数重载的运算符,*是作为非成员函数重载的运算符。 operator+有一个参数,operator*有两个参数;(8) 在+中,对象之间的相互通信通过 调用成员函数来实现。(9) Franction operator +(Franction,Franction); Franction Franction 这个基类中的成员函数表示纯虚函数。(13) 如果一个类至少有一个纯虚函数,那么就称该类为抽象类。(14) 纯虚函数是一种特殊的虚函数,它没有具体的定义;抽象类是指具有纯虚函数的类;抽象类只能作为基类来使用,其纯虚函数的定义同派生类给出。(15) 抽象类的特性: 不能定义其对象。(16) 抽象类

25、应含有至少一个纯虚函数。(17) 类是类的公有派生类,类和类中都定义了虚函数 fun(), p 是一个指向类对象的指针,则 p-A::func()将调用类中的函数 func()。(18) 在+中,用于实现运行时多态性的是虚函数。(19) Class APublic:Virtual void func1()void func2() ;Class B: public APublic:Void func1()cout(提取操作符) 连用,用于输入;cout 为标准输出流对象,与 连用进行输入时,将空格与换行当作分隔符,使用 getline() 成员函数进行输入时可以指定输入分隔符。(3)头文件 io

26、stream 中定义了个标准流对象 cin, cout, cerr, clog。(4)每一个输入/输出流对象都维护一个格式状态字,用它表示汉对象当前的格式状态并控制流的格式。+提供了使用操纵符与格式状态字 ,来控制流的格式的方法。(5)格式控制的成员函数通过流对象调用;操纵符直接用在流中,但使用函数形式的操纵符要包含 iomanip 头文件。(6)在 ios 类中,除了提供控制数据流格式标志、操纵符、成员函数,还提供了流的错误侦测函数与错误状态位,用于标识流的状态,常用的错误侦测函数有 good(), eof(), fail(), bad()对应的错误状态位为 goodbit, eof, bi

27、t, failbit, badbit。(7)文件输入是指从文件向内存读入数据;文件输出则指从内存向文件输出数据。文件的输入输出首先要建立输入文件流,与打开的文件连接;然后从文件流中读入数据到内存;最后关闭文件流。在打开文件、对文件读写时要使用是否成功的判断来保证文件操作的正确。(8)文本文件是存储 ASSCII 码字符的文件,文本文件的输入可用(提取操作符)从输入文件流中提取字符实现。文本文件的输出可用 , reinterpret_cast进行转换。(10)设定、返回文件读指针位置的函数分别为 seekg() , tellg(); 设定、返回文件写指针位置的函数分别为 seekp(), tellp()。2.(1)要进行文件的输出,除了包含头文件 iostream 外,还要包含 fstream 头文件。(3)char *str; cinstr; coutstr; 若输入 abcd 1234 则输出出错或乱码。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报