版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第一章习题答案1.什么是结构化程序设计方法?这种方法有哪些优点和缺点?【解答】结构化程序设计方法是指20世纪60年代开始出现的高级语言程序设计方法,由于采用了数据结构化、语句结构化、数据抽象和过程抽象等概念,使程序设计在符合客观事物与逻辑的基础上更进了一步。结构化程序设计的思路是:自顶向下、逐步求精。程序结构由具有一定功能的若干独立的基本模块(单元)组成,各模块之间形成一个树状结构,模块之间的关系比较简单,其功能相对独立,模块化通过子程序的方式实现。结构化程序设计方法使高级语言程序设计开始变得普及,并促进了计算机技术的深入应用。优点:结构化程序设计方法采用了功能抽象、模块分解与组合,以及自顶向下、逐步求精的方法,能有效地将各种复杂的任务分解为一系列相对容易实现的子任务,有利于软件开发和维护;缺点:结构化程序设计存在的主要问题是,程序的数据和对数据的操作相互分离,若数据结构改变,程序的大部分甚至所有相关的处理过程都要进行修改。因此,对于开发大型程序具有一定的难度,软件的可重用性差,维护工作量大,不完全符合人类认识世界的客观规律。什么面向对象程序设计方法?有哪些优点?【解答】面向对象程序设计方法采用与客观世界相一致的方法设计软件,其设计方法是模拟人类习惯的思维方式,使软件开发的方法与过程尽可能接近人类认识世界、解决问题的方法与过程,从而使描述问题的问题空间(即问题域)与实现解法的解空间(即求解域)在结构上尽可能一致。是一种运用对象、类、封装、继承、多态和消息等概念来构造、测试、重构软件的方法。优点:面向对象程序设计方法使得开发的软件产品易重用、易修改、易测试、易维护、易扩充,降低了软件开发的复杂度。达到了软件工程的3个主要目标:重用性、灵活性和扩展性。适合大型的、复杂的软件开发。3.面向对象与面向过程程序设计有哪些不同点?【解答】面向过程的程序设计方法将客观事物中本质上密切相关、相互依赖的数据和对数据的操作相互分离,这种实质上的依赖与形式上的分离使得大型程序既难以编写,也难以调试、修改和维护,代码的可重用性和共享性差。而面向对象程序设计方法是一种以对象为基础,以事件或消息来驱动对象执行相应处理的程序设计方法。它将数据及对数据的操作封装在一起,作为一个相互依存、不可分离的整体——对象;它采用数据抽象和信息隐蔽技术,将这个整体抽象成一种新的数据类型——类。类中的大多数数据,只能通过本类方法进行操作和处理。面向对象程序设计以数据为中心而不是以功能为中心来描述系统,因而非常适合于大型应用程序与系统程序的开发。在程序结构上,面向对象程序与面向过程程序也有很大的不同。面向过程的程序主要由顺序结构、选择结构和循环结构组成,程序的基本单位是函数,程序的执行顺序也是确定的。而面向对象程序由类的定义和类的使用两部分组成,程序的基本单位是类,在主程序内定义对象,并确定对象之间消息的传递规律,程序中的所有操作都是通过向对象发送消息来实现的,对象接到消息后,通过消息处理函数完成相应的操作。4.面向对象程序设计有哪些重要特征?【解答】面向对象程序设计的基本特征主要有抽象性、封装性、继承性和多态性。抽象性:面向对象程序设计的基本要素是抽象。抽象就是从众多事物中抽取出共同的、本质的特征,形成类。在面向对象程序设计中,封装性:封装是面向对象程序设计方法的一个重要特征,它是将对象的属性和行为结合成一个独立的单位,并尽可能隐蔽对象的内部细节。封装有两个含义:一是把对象的全部属性和行为结合在一起,形成一个不可分割的独立单位。对象的属性值(除了公有的属性值)只能由这个对象的行为来读取和修改;二是尽可能隐蔽对象的内部细节,对外形成一道屏障,与外部的联系只能通过外部接口实现。继承性:多态性:是面向对象程序设计的另一个重要的特征对象根据所接收的消息而做出动作。“一个接口,多种形态”,即同一消息为不同的对象接收时可产生完全不同的行为,这种现象称为多态性。5.什么是面向对象方法的封装性?它有何优缺点?【解答】封装性指将对象的属性和行为代码封装在对象的内部,形成一个独立的单位,并尽可能隐蔽对象的内部细节。封装性是面向对象方法的一个重要原则,C++面向对象方法的封装特性包含以下两层含义:第一层含义是将对象的全部属性和行为封装在对象内部,形成一个不可分割的独立单位。对象的属性值(公有属性值除外)只能由这个对象的行为来读取和修改。第二层含义是“信息隐蔽”,即尽可能隐蔽对象的内部细节,对外形成一道屏障,只保留有限的对外接口与外部发生联系。面向对象方法的封装性具有以下特点:(1)封装性使对象以外的事物不能随意获取对象的内部属性,有效地避免了外部错误对它产生的影响,大大减轻了软件开发过程中查错的工作量,减小了排错的难度。(2)封装性使得当程序需要修改对象内部的数据时,减少了因为内部修改对外部的影响。(3)封装性使对象的使用者与设计者可以分开,使用者不必知道对象行为实现的细节,而只使用设计者提供的外部接口即可。(4)封装性事实上隐蔽了程序设计的复杂性,提高了代码重用性,降低了软件开发的难度。(5)面向对象程序设计方法的信息隐蔽作用体现了自然界中事物的相对独立性,程序设计者与使用者只需关心其对外提供的接口,而不必过分注意其内部细节,即主要关注能做什么,如何提供这些服务等。6.面向对象程序设计为什么要应用继承机制?【解答】在面向对象程序设计中,根据既有类(父类)派生出新类(子类)的现象称为类的继承机制,亦称为继承性。面向对象方法的继承性是联结类与类的一种层次模型。继承是面向对象程序设计能够提高软件开发效率的重要原因之一。继承意味着派生类中无须重新定义在父类中已经定义的属性和行为,而是自动地、隐含地拥有其父类的全部属性与行为。继承机制允许和鼓励类的重用,派生类既具有自己新定义的属性和行为,又具有继承下来的属性和行为。当派生类又被它更下层的子类继承时,它继承的及自身定义的属性和行为又被下一级子类继承下去。继承是可以传递的,符合自然界中特殊与一般的关系。继承性具有重要的实际意义,它简化了人们对事物的认识和描述。比如我们认识了飞行器的特征之后,再考虑飞机、飞船和弹道时,由于它们都具有飞行器的共性,于是可以认为它理所当然地具有飞行器的一般本质特征,从而只需把精力用于发现和描述飞机、飞船和导弹独有的特征。面向对象程序设计中的继承性是对客观世界的直接反映。通过类的继承,能够实现对问题的深入抽象描述,反映人类认识问题的发展过程。7.什么是面向对象程序设计中的多态性?【解答】面向对象程序设计的多态性指父类中定义的属性或行为,被派生类继承之后,可以具有不同的数据类型或表现出不同的行为特性。如类中的同名函数可以对应多个具有相似功能的不同函数,可使用相同的调用方式来调用这些具有不同功能的同名函数。多态性使得同一个属性或行为(如函数)在父类及其各派生类中具有不同的语义,面向对象的多态特性使软件开发更科学、更方便和更符合人类的思维习惯,能有效地提高软件开发效率,缩短开发周期,提高软件可靠性,使所开发的软件更健壮。8.什么是面向对象中的消息?一条消息由哪几部分组成?【解答】在面向对象程序设计中,消息是描述事件发生的信息,是对象之间发出的行为请求。事件一般由多个消息组成。在面向对象方法中,消息是向某个对象提出执行该对象具有的特定服务的申请,不同对象之间通过发送消息向对方提出服务请求,接受消息的对象主动完成所请求的服务。通常一条消息由接受消息的对象、消息名称和若干消息参数三部分组成。面向对象中的消息机制为不同对象之间提供了一个动态联系的途径,使它们的行为能互相配合,9.为什么说C++是混合型面向对象程序设计语言?【解答】C++是美国Bell实验室于20世纪80年代在C语言的基础上成功开发出来的,是目前已经得到广泛应用的混合型面向对象程序设计语言。C++既可以用于结化程序设计,又可以用于面向对象程序设计,因此是一种混合型面向对象程序设计语言。C++保留了C语言的全部优点,兼容C语言的语法,弥补了C语言的缺陷,且C程序不经修改可以直接在C++环境中使用。同时,C++还增加了面向对象的方法与机制,全面支持面向对象程序设计方法。
什么是命名空间,如何访问命名空间的成员?【解答】为了解决不同文件中同名变量的问题,C++标准中引入命名空间的概念。命名空间(namespace)是一种特殊的作用域,命名空间可以由程序员自己来创建,可以将不同的标识符集合在一个命名作用域内,这些标识符可以类、对象、函数、变量、结构体、模板以及其他命名空间等。在作用域范围内使用命名空间就可以访问命名空间定义的标识符。有3种访问方法:直接指定标识符,访问方式为:命名空间标识符名∷成员名。使用usingnamespace命令使用using关键词声明什么是内联函数,它有什么特点?哪些函数不能定义为内联函数?【解答】用inline关键字声明或定义的函数称为内联函数。C++中对于功能简单、规模小、使用频繁的函数,可以将其设置为内联函数。内联函数(inlinefunction)的定义和普通函数相同,但C++对它们的处理方式不一样。在编译时,C++将用内联函数程序代码替换对它每次的调用。这样,内联函数没有函数调用的开销,即节省参数传递、控制转移的开销,从而提高了程序运行时的效率。但是,由于每次调用内联函数时,需要将这个内联函数的所有代码复制到调用函数中,所以会增加程序的代码量,占用更多的存储空间,增大了系统空间方面的开销。因此,内联函数是一种空间换时间的方案。函数体内有循环语句和switch语句,递归调用的函数不能定义为内联函数。什么是函数重载?在函数调用时,C++是如何匹配重载函数的?【解答】函数重载是指两个或两个以上的函数具有相同的函数名,但参数类型不一致或参数个数不同。编译时编译器将根据实参和形参的类型及个数进行相应地匹配,自动确定调用哪一个函数。使得重载的函数虽然函数名相同,但功能却不完全相同。在函数调用时,C++是匹配重载函数规则如下:首先寻找一个精确匹配,如果能找到,调用该函数;其次进行提升匹配,通过内部类型转换(窄类型到宽类型的转换)寻求一个匹配,如char到int、short到int等,如果能找到,调用该函数;最后通过强制类型转换寻求一个匹配,如果能找到,调用该函数。设置函数参数的默认值有何作用?【解答】C++中允许函数提供默认参数,也就是允许在函数的声明或定义时给一个或多个参数指定默认值。在调用具有默认参数的函数时,如果没有提供实际参数,C++将自动把默认参数作为相应参数的值什么叫引用,使用引用时需要注意哪些问题?【解答】引用是一个变量的别名。使用引用时,必须在定义时进行初始化,不能在定义完后再赋值。6.new运算符的作用是什么?delete运算符的作用是什么?【解答】在C++程序中,new是动态分配内存的运算符,自动计算需要分配的空间。delete是撤销动态申请的内存运算符。delete与new通常配对使用,建立堆对象时使用new运算符、删除堆对象时delete使用运算符。7、#include"stdafx.h"#include"iostream"usingnamespacestd;intMin(intx1,intx2);intMin(intx1,intx2,intx3);intMin(intx1,intx2,intx3,intx4);int_tmain(intargc,_TCHAR*argv[]){ intx1,x2,x3,x4;cout<<"inputx1,x2,x3,x4"<<endl;cin>>x1>>x2>>x3>>x4;cout<<Min(x1,x2)<<endl;cout<<Min(x2,x3,x4)<<endl;cout<<Min(x1,x2,x3,x4)<<endl; getchar(); return0;}intMin(intx1,intx2){return(x1<x2?x1:x2);}intMin(intx1,intx2,intx3){inty;y=x1<x2?x1:x2;return(y<x3?y:x3);}intMin(intx1,intx2,intx3,intx4){inty1,y2;y1=x1<x2?x1:x2;y2=x3<x4?x3:x4;return(y1<y2?y1:y2);}8、#include"iostream"#include<cmath>usingnamespacestd;#definepi3.141592doubleArea(doubleR);doubleArea(doublea,doubleb);doublePerim(doubleR);doublePerim(doublea,doubleb);int_tmain(intargc,_TCHAR*argv[]){doubler; doublem; doublen; cout<<"请输入圆的半径"<<endl; cin>>r; cout<<"圆的面积为:"<<Area(r)<<""<<"圆的周长为:"<<Perim(r)<<endl; cout<<"请输入长方形的边长"<<endl; cin>>m>>n; cout<<"长方形的面积为:"<<Area(m,n)<<""<<"长方形的周长为:"<<Perim(m,n)<<endl; cout<<"请输入正方形的边长"<<endl; cin>>m; cout<<"正方形的面积为:"<<Area(m,m)<<""<<"正方形的周长为:"<<Perim(m,m)<<endl; return0;}doubleArea(doubleR){doubles;s=pi*R*R; returns;}doubleArea(doublea,doubleb){doubles;s=a*b; returns;}doublePerim(doubleR){doublep;p=2*pi*R; returnp;}doublePerim(doublea,doubleb){doublep;p=2*(a+b); returnp;}9、#include<fstream>#include<iostream>usingnamespacestd;int_tmain(intargc,_TCHAR*argv[]){ ofstreamoutData("D:\\data.txt");ifstreaminData; intx,i,b[10]; for(i=0;i<10;i++) {cin>>x; outData<<x<<""; } outData.close(); inData.open("D:\\data.txt"); //while(!inData.eof()) for(intj=0;j<10;j++) {inData>>b[j];} inData.close(); ints=0; for(intm=0;m<10;m++) {s+=b[m]; cout<<b[m]<<""; } cout<<endl; cout<<"数据总和为:"<<s<<endl; getchar(); return0;}10、(1)#include<fstream>#include<iostream>usingnamespacestd;int_tmain(intargc,_TCHAR*argv[]){ ofstreamoutData("C:\\student.dat");//charname[8],id[10],pro[8]; intmath,english; for(inti=0;i<3;i++) {cout<<"输入学生姓名:";cin>>name; cout<<"输入学生学号:";cin>>id; cout<<"输入学生专业:";cin>>pro; cout<<"输入高数成绩:";cin>>math; cout<<"输入英语成绩:";cin>>english; outData<<name<<""<<id<<""<<pro<<""<<math<<""<<english<<endl; } outData.close(); return0;}(2)#include<fstream>#include<iostream>usingnamespacestd;int_tmain(intargc,_TCHAR*argv[]){ ifstreaminData("C:\\student.dat"); charname1[8],id1[10],pro1[8]; intmath1,english1; for(inti=0;i<8;i++) {inData>>name1>>id1>>pro1>>math1>>english1; cout<<"姓名:"<<name1<<endl; cout<<"学号:"<<id1<<endl; cout<<"专业:"<<pro1<<endl; cout<<"高数成绩:"<<math1<<endl; cout<<"英语成绩:"<<english1<<endl; } inData.close(); getchar(); return0;}
第三章在类的定义中,包含几类成员?分别是什么?在类的定义中,包含两类成员。一类是代表对象属性的数据成员,另一类是实现对象行为的成员函数。C++中类成员的访问控制权限有哪几种?各有何特点?C++对类的成员提供了public(公有类型)、private(私有类型)和protected(保护类型)三种不同的访问权限。public声明成员为公有成员。具有这个访问控制权限的成员是完全公开的,即该成员不但可以被它所在类的成员函数及该类的友元函数访问,也可以被和该类对象处在同一作用域内的任何函数访问。private声明成员为私有成员。具有这个访问控制权限的成员对类外是完全保密的,即只能被它所在类中的成员函数和该类的友元函数访问。protected声明成员为保护成员。具有这个访问控制权限的成员,外界是无法直接访问的。它只能被它所在类及从该类派生的子类的成员函数及友元函数访问。什么是构造函数和析构函数?其作用各是什么?对构造函数和析构函数有哪些要求?构造函数(Constructor)和析构函数(Destructor)是两种特殊的成员函数,构造函数用来完成在声明对象的同时,对对象中的数据成员进行初始化;析构函数用来完成当对象的生命期结束(删除对象)时,自动被执行,进行一些必要的清理工作。对构造函数的要求包括:(1)名称必须有类名相同;(2)没有返回值类型,也不能指定为void;(3)构造函数可以有任意个任意类型的参数;(4)如果没有显式的定义构造函数,系统会自动生成一个默认的构造函数。这个构造函数不含有参数,也不对数据成员进行初始化,只负责为对象分配存储空间;(5)如果显式的为类定义了构造函数,系统将不再为类提供默认构造函数;(6)定义对象时,系统会自动调用构造函数;(7)构造函数可以重载;(8)构造函数一般被定义为公有访问权限。对构造函数的要求包括:(1)函数名由“~”加类名组成;(2)函数没有参数、没有返回值,而且不能重载;(3)一个类有且仅有一个析构函数,且应为public;(4)在对象的生命期结束前,由系统自动调用析构函数。在C++中,对析构函数有哪些要求?对构造函数的要求包括:(1)函数名由“~”加类名组成;(2)函数没有参数、没有返回值,而且不能重载;(3)一个类有且仅有一个析构函数,且应为public;(4)在对象的生命期结束前,由系统自动调用析构函数。在C++中,函数的参数传递有几方式?分别是什么?C++语言中,函数的参数传递方式有3种,分别是值传递、指针传递和引用传递。6.什么是this指针?它有什么作用?this指针是一个隐含于每一个成员函数中的特殊指针。它指向正在操作该成员函数的对象,当一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数。每次成员函数存取数据成员时,C++编译器将根据this指针所指向的对象来确定应该引用哪一个对象的数据成员。7.什么是拷贝构造函数?什么情况下调用此函数?拷贝构造函数是一种特殊的构造函数,它具有一般构造函数的所有特性,但其形参是本类对象的引用。其作用是使用一个已经存在的对象(由拷贝函数的参数指定)去初始化同类的一个新对象。调用拷贝构造函数的情况有3种:(1)明确表示由一个对象初始化另一个对象;(2)当对象作为函数实参传递给函数形参时;(3)当对象作为函数的返回值,创建一个临时对象。8.什么是组合类?创建和删除组合类时,构造函数和析构函的调用顺序是什么?组合类是指一个类内嵌其他类的对象作为本类的成员。两者之间是包含与被包含的关系。在创建一个组合类的对象时,不仅它自身的构造函数将被调用,而且其内嵌对象的构造函数也将被调用。这时构造函数调用的顺序为:①调用内嵌对象的构造函数,调用顺序按照内嵌对象在组合类的声明中出现的先后顺序依次调用;②执行本类构造函数的函数体;③析构函数的调用顺序与构造函数刚好相反。9.设计一个名为Rectangle的矩形类,其属性为矩形的左上角和右下角两个点的坐标,能计算和输出矩形的周长和面积。#include"stdafx.h"#include"iostream"usingnamespacestd;structPoint{ inta; intb;};classRectangle{PointtopLeft;PointbottomRight;public: Rectangle(Pointa,Pointb); intArea(); intSideLength();};intmain(){ Pointm,n; m.a=3; m.b=4; n.a=12; n.b=10; Rectanglerect(m,n); cout<<"矩形的面积为:"<<rect.Area()<<endl; cout<<"矩形的周长为:"<<rect.SideLength()<<endl;return0;}Rectangle::Rectangle(Pointa,Pointb){topLeft=a; bottomRight=b;}intRectangle::Area(){ intx=bottomRight.a-topLeft.a; inty=bottomRight.b-topLeft.b;returnx*y;}intRectangle::SideLength(){ intx=bottomRight.a-topLeft.a; inty=bottomRight.b-topLeft.b;return2*(x+y);}10.#include"stdafx.h"classdatatype{ charx; inty; doublez;public: datatype(charx1); datatype(inty1); datatype(doublez1);};datatype::datatype(charx1){ x=x1;}datatype::datatype(inty1){ y=y1;}datatype::datatype(doublez1):z(z1){}int_tmain(intargc,_TCHAR*argv[]){ return0;}11.一矩形体育场如下图所示,现在需在其周围建一矩形过道,并在四周围安上栅栏。栅栏价格为50元/米,过道造价为240元/平方米。过道宽为3米,体育场的长宽由键盘输入。请编写程序计算并输出过道和栅栏的造价。#include"stdafx.h"#include"iostream"usingnamespacestd;classRectangle{ doublelength; doublewidth;public: Rectangle(doubleLength=10.,doubleWidth=5.); doubleArea(); doubleSideLength();};intmain(){ inta=50,b=240; doublex,y; cout<<"请输入矩形的长和宽:"; cin>>x>>y; cout<<endl; Rectanglerect1(x,y),rect2(x+3,y+3); cout<<"栅栏的长度为:"<<rect2.SideLength()<<",造价为:"<<rect2.SideLength()*a<<endl;doublearea12; area12=rect2.Area()-rect1.Area(); cout<<"过道的面积为:"<<area12<<",造价为:"<<area12*b<<endl; return0;}Rectangle::Rectangle(doubleLength,doubleWidth){ length=Length; width=Width;}doubleRectangle::Area(){ returnlength*width;}doubleRectangle::SideLength(){ return2*(length+width);}12.定义一个员工类,员工信息由编号、姓名、性别、年龄、职务、职称、岗位、薪酬等组成,要求利用队列实现员工的增加、删除和输出等功能。#include"stdafx.h"#include"iomanip"#include"iostream"usingnamespacestd;#defineMAXSIZE5000structEmployees{longno;//编号 charname[10];//姓名 charsex[3];//性别 intage;//年龄 charpositions[20];//职务 charprofessionalTitles[20];//职称 charjobs[20];//岗位 floatremuneration;//薪酬};classEmployees_c{private: EmployeesEmployees_struct[MAXSIZE]; inttotal;public: Employees_c(); intInsert_seq(inti,Employeesx);//插入第i员工的信息 intDelete_seq(inti);//删除第i个员工信息 voidPrint_seq();//打印所有员工信息};voidmenu();intmain(){ Employees_cEmployees_Object; intn; boolm=true; while(m) { menu(); cin>>n; switch(n) { case1: { inti; Employeesx; cout<<"请输入插入位置:"; cin>>i; cout<<"请输入员工的编号、姓名、性别、年龄、"<<"职务、职称、岗位和薪酬:"<<endl; cin>>x.no>>>>x.sex>>x.age>>x.positions>>fessionalTitles>>>>x.remuneration; Employees_Object.Insert_seq(i,x); cout<<"插入后的情况:"<<endl; Employees_Object.Print_seq(); break; } case2: { inti; cout<<"请输入删除位置:; cin>>i; Employees_Object.Delete_seq(i); cout<<"删除后的情况:"<<endl; Employees_Object.Print_seq(); break; } case0:m=false; } } return0;}voidmenu(){ cout<<endl; cout<<"1.插入"<<endl; cout<<"2.删除"<<endl; cout<<"0.退出"<<endl; cout<<endl; cout<<"请选择:";}Employees_c::Employees_c(){total=0;}intEmployees_c::Insert_seq(inti,Employeesx){ intj; if(total==MAXSIZE) { cout<<"tableisfull"<<endl; return-1; } if(i<1||i>(total+1)) { cout<<"placeiswrong!"<<endl; return0; }for(j=total-1;j>=i-1;j--) { Employees_struct[j+1]=Employees_struct[j]; }Employees_struct[i-1]=x; ++total; return1;}intEmployees_c::Delete_seq(inti){ intj; if(i<1||i>total) { cout<<"thiselementdon'texist!"<<endl; return-1; } for(j=i;j<=total-1;j++) { Employees_struct[j-1]=Employees_struct[j]; } --total; return1;}voidEmployees_c::Print_seq(){ inti; for(i=0;i<=total-1;i++) { cout<<Employees_struct[i].no<<setw(10)<<Employees_struct[i].name<<setw(10)<<Employees_struct[i].sex<<setw(10)<<Employees_struct[i].age <<setw(10)<<Employees_struct[i].positions<<setw(10)<<Employees_struct[i].professionalTitles <<setw(10)<<Employees_struct[i].jobs<<setw(10)<<Employees_struct[i].remuneration<<endl; } cout<<endl;}13.设计一个复数类,要求对其构造函数进行重载。#include"stdafx.h"classComplex{ doublereal,imag;public: Complex(); Complex(doublereal1); Complex(doublereal1,doubleimag1);};Complex::Complex(){ real=0.; imag=0.;}Complex::Complex(doublereal1){ real=real1; imag=0.;}Complex::Complex(doublereal1,doubleimag1){ real=real1; imag=imag1;}
第四章1.静态数据成员是一种什么样的数据成员类型?静态数据成员是一种特殊的数据成员类型,它是类的所有对象共享的数据成员,而不只是某个对象的数据成员。使用静态数据成员的好处在于不但实现了数据共享,而且可以节省所使用的内存空间。2.如何对静态数据成员进行初始化?静态数据成员不能在类的构造函数中初始化,也不可在类的_体内进行赋初值,它的初始化工作只能在类外进行,并且在对象生成之前进行。3.类的友元有哪几种?类的友元有三种:1)该类外部的普通函数;2)另一个类中的成员函数;3)另一个类。4.对象有哪几种生存期?对象可分为局部对象、静态对象、全局对象和动态对象四种生存期5.常量对象的特点是什么?常量对象的特点是它的数据成员的值在对象的整个生存期内都不能被修改。6.(1)建立一个类,该类具有const和非const成员函数。(2)创建这个类的const和非const对象,并用不同类型的对象调用不同类型的成员函数。#include"stdafx.h"#include<iostream>usingnamespacestd;classA{public: voidpoint(); voidoutput()const;};int_tmain(intargc,_TCHAR*argv[]){ Aconsta1; Aa2; a1.output(); a2.output(); a2.point(); return0;}voidA::point(){ cout<<"point"<<endl;}voidA::output()const{ cout<<"output"<<endl;}7.编写一个类,统计目前存在多少个该类的对象。#include"stdafx.h"#include<iostream>usingnamespacestd;classA{ staticinttotal;public: A() { total++; cout<<"当前类的对象总数为:"<<total<<endl; }~A(){ total--; cout<<"当前类的对象总数为"<<total<<endl;}};voidf(){ Aaa,bb,cc;}intA::total=0;int_tmain(intargc,_TCHAR*argv[]){ Aa1,a2,a3; f(); Ab1,b2,b3; return0;}8.编写一个学生类,学生信息包括姓名、学号、年龄、性别和成绩;统计学生的总人数及总成绩,并输出。#include"stdafx.h"#include<iostream>usingnamespacestd;classStudent{ intno; charname[10]; charsex[3]; intage; doublescore; staticinttotalNumber; staticdoubletotalScore;public: Student(intno_,char*name_,char*sex_,intage_,doublescore_); staticvoidOutput(); voidStudentInformation();};intStudent::totalNumber=0;doubleStudent::totalScore=0;int_tmain(intargc,_TCHAR*argv[]){ Studentstu1(1001,"张三","男",18,97.5); stu1.StudentInformation(); Studentstu2(1002,"李四","女",19,83.); stu2.StudentInformation(); Studentstu3(1003,"王五","男",17,93.); stu3.StudentInformation(); Studentstu4(1004,"郭六","女",20,62.5); stu4.StudentInformation(); Studentstu5(1005,"任七","男",18,77.); stu5.StudentInformation(); Student::Output(); return0;}Student::Student(intno_,char*name_,char*sex_,intage_,doublescore_){ no=no_; strcpy(name,name_); strcpy(sex,sex_); age=age_; score=score_; totalNumber++; totalScore+=score;}voidStudent::StudentInformation(){ cout<<"学号:"<<no<<""<<"姓名:"<<name<<""<<"性别:"<<sex<<""<<"年龄:"<<age<<""<<"成绩:"<<score<<endl;}voidStudent::Output(){ cout<<"学生总数:"<<totalNumber<<""<<"总成绩:"<<totalScore<<""<<"平均成绩:"<<totalScore/totalNumber<<endl;}9.编写一个学生类。(1)输出每个学生的姓名、学号、成绩;(2)统计并输出学生的总人数、总成绩、平均成绩、最高成绩、最低成绩。#include"stdafx.h"#include<iostream>usingnamespacestd;classStudent{ intno; charname[10]; doublescore; staticinttotalNumber; staticdoubletotalScore; staticdoublelowestScore; staticdoublehighestScore;public: Student(intno_,char*name_,doublescore_); staticvoidOutput(); voidStudentInformation();};intStudent::totalNumber=0;doubleStudent::totalScore=0;doubleStudent::highestScore=0.;doubleStudent::lowestScore=100.;int_tmain(intargc,_TCHAR*argv[]){ Studentstu1(1001,"张三",97.5); stu1.StudentInformation(); Studentstu2(1002,"李四",83.); stu2.StudentInformation(); Studentstu3(1003,"王五",93.); stu3.StudentInformation(); Studentstu4(1004,"郭六",62.5); stu4.StudentInformation(); Studentstu5(1005,"任七",77.); stu5.StudentInformation(); Student::Output(); return0;}Student::Student(intno_,char*name_,doublescore_){ no=no_; strcpy(name,name_); score=score_; totalNumber++; totalScore+=score; if(score>highestScore) highestScore=score; if(score<lowestScore) lowestScore=score;}voidStudent::StudentInformation(){ cout<<"学号:"<<no<<""<<"姓名:"<<name<<""<<"成绩:"<<score<<endl;}voidStudent::Output(){ cout<<"学生总数:"<<totalNumber<<""<<"总成绩:"<<totalScore<<""<<endl; cout<<"平均成绩:"<<totalScore/totalNumber<<""<<"最高成绩"<<highestScore<<""<<"最低成绩"<<lowestScore<<""<<endl;}10.定义复数类和二维向量类,复数具有实部和虚部,二维向量有两个向量。利用友元类将复数转换为二维向量。#include"stdafx.h"#include<iostream>usingnamespacestd;classComplex{doublereal;doubleimag;public:Complex(doubler,doublei);friendclassVector;};classVector{doublex,y;public:voidChange(Complexc);voidPrint(Complexc);};intmain(){Complexc(1.2,3.4);Vectorv;v.Change(c);v.Print(c);return0;}Complex::Complex(doubler,doublei){real=r;imag=i;}voidVector::Change(Complexc){x=c.real;y=c.imag;}voidVector::Print(Complexc){//输出复数cout<<"复数:";cout<<c.real;if(c.imag>0)cout<<"+";cout<<c.imag<<"i"<<endl;//输出二维向量cout<<"二维向量:";cout<<"("<<x<<","<<y<<")"<<endl;}
教材第五章答案1.什么是继承性?答:所谓继承(Inheritance)就是在一个已存在的类的基础上建立一个新类,实质就是利用已有的数据类型定义出新的数据类型。2.C++的继承分为哪两类?答:单继承和多继承。3.试说明什么是虚基类,其有何用处。答:将共同基类设置为虚基类,这样从不同的途径继承过来的同名成员只有一个副本,这样就不会再会引起二义性问题。4.什么是同名覆盖?答:如果在派生类中声明了与基类成员相同的新成员,派生类的新成员将覆盖基类的同名成员。此时,如果在派生类或派生类对象中直接调用该成员名就只能访问到派生类中声明的同名成员,这被称为同名覆盖。5.类的继承有几种方式?试比较各种继承方式派生类对基类成员的继承。答:在C++程序设计中,提供了3种继承方式:公有继承(public)、私有继承(private)和保护继承(protected)。对于不同的继承方式,会导致基类成员原来的访问属性在派生类中发生变化。下表所示为不同继承方式下,基类成员各访问属性的变化情况。 访问属性与继承的关系访问属性继承方式publicprotectedprivatepublicpublicprotectedprivateprotectedprotectedprotectedprivateprivateprivateprivateprivate6.什么是赋值兼容规则?答:所谓赋值兼容规则就是在公有继承方式下,对于某些场合,一个派生类的对象可以作为基类的对象来使用。7.什么是子类型?答:子类型的概念涉及到行为的共享,它与继承和派生有着紧密的联系。所谓子类型,是指当一个类型至少包含了另一个类型的所有行为,则称该类型是另一个类型的子类型。8.多继承中,在什么情况下会出现二义性?如何消除二义性?答:子类型的概念涉及到行为的共享,它与继承和派生有着紧密的联系。所谓子类型,是指当一个类型至少包含了另一个类型的所有行为,则称该类型是另一个类型的子类型。解决派生类的不同基类有同名成员的二义性,有几种方法:使用作用域标识符、使用同名覆盖的原则、虚基类。9.单继承中,派生类的构造函数的格式如何定义?答:在C++中,派生类构造函数的一般性声明语法如下:<派生类名>::<派生类名>(基类形参,内嵌对象形参,本类形参):<基类名>(参数表),<内嵌对象1>(参数表1),<内嵌对象2>(参数表2),…,<内嵌对象n>(参数表n){
本类成员初始化赋值语句;
…};10.多继承中,派生类的构造函数的格式如何定义?答:在多重继承的情况下,派生类的构造函数一般性声明语法如下:<派生类名>::<派生类名>(基类形参,内嵌对象形参,本类形参):<基类名1>(参数表),<基类名2>(参数表),…,<基类名n>(参数表),<内嵌对象1>(参数表1),<内嵌对象2>(参数表2),…,<内嵌对象n>(参数表n){ 本类成员初始化赋值语句; …};11.试说明派生类和基类之间存在什么样的关系?答:基类是派生类的父类,基类派生出派生类;12.声明一个Shape基类,在此基础上派生出Rectangle类和Circle类,Rectangle类又派生出Square类。使用GetArea()函数分别计算Rectangle、Circle和Square的面积。答:#include<iostream.h>#definePI3.1415926classshape{protected:doubles;public:voidshow(){cout<<"s="<<s<<endl;}};classRectangle:publicshape{doublex,y;public:Rectangle(doublex1=0,doubley1=0) {x=x1;y=y1;}voidGetArea() {s=x*y;} };classCircle:publicshape{doubler;public:Circle(doubler1=0) {r=r1;}voidGetArea() {s=r*r*PI;}};classSquare:publicRectangle{doublea;public:Square(doublea1=0){a=a1;}voidGetArea() {s=a*a;}};13.编写一个学生和教师数据输入/输出的程序。学生数据包括编号、姓名、班号和成绩;教师数据包括编号、姓名、职称和部门。要求设计一个person类,作为学生数据操作类student和教师数据操作类teacher的基类。答:方法一#include<iostream>#include<string>usingnamespacestd;classperson//定义一个基类 {protected:intno;stringname;//姓名};classteacher:publicperson//基类派生出教师类 {stringzc;//职称doublewages;//工资public:voidinput(){cin>>no>>name>>zc>>wages;}voidoutput(){cout<<"no"<<no<<"name"<<name<<"zc"<<zc<<"wages"<<wages<<endl;}};classstudent:publicperson/{stringzy;//专业班级doublescore;//public:voidinput(){cin>>no>>name>>zy>>score;}voidoutput(){cout<<"no"<<no<<"name"<<name<<"zy"<<zy<<"score"<<score<<endl;}};int_tmain(intargc,_TCHAR*argv[]){teachertec; studentstu; tec.input(); tec.output(); stu.input(); stu.output(); return0;}(方法二)#include<iostream>#include<string>usingnamespacestd;classperson//定¨义?一?个?基ù类え {intno;stringname;//姓?名?public:voidinput(){cin>>no>>name;}voidoutput(){cout<<"no"<<no<<""<<"name"<<name<<endl;}};classteacher:publicperson//基ù类え 派é生Θ 出?教ì师簗类え {stringzc;//职°称?doublewages;//工¤资哩 public:voidinput(){person::input();cin>>zc>>wages;}voidoutput(){person::output();cout<<"zc"<<zc<<"wages"<<wages<<endl;}};classstudent:publicperson//基ù类え 派é生Θ 出?学§生Θ 类え {stringzy;//专痢 业唉 班悒 级?doublescore;//public:voidinput(){person::input();cin>>zy>>score;}voidoutput(){person::output();cout<<"zy"<<zy<<"score"<<score<<endl;}};int_tmain(intargc,_TCHAR*argv[]){ teachertec; studentstu; tec.input(); tec.output(); stu.input(); stu.output(); return0;}14.编写一个小型公司人员工资管理程序,要求设计合理的基类和派生类,实现工资管理任务。下表是公司经理、兼职人员、销售经理和销售员当月工资计算方法。人员类别固定工资/元计时工资/(元/小时)当月销售总额提成公司经理10000无无兼职人员无150无销售经理6000无1%销售员无无5%答:#include<iostream>#include"string"usingnamespacestd;classemployee//定义雇员类 {protected: intno;//编号 charname[10];//姓名 floatsalary;//工资public: employee() { cout<<"雇员编号:"<<endl; cin>>no;//输入编号 cout<<"姓名:"<<endl; cin>>name;//输入姓名 salary=0; } voidpay(); voiddisplay();};classtechnician:publicemployee//定义兼职人员类 {private: floathourlyrate;//计时工资 intworkhours;//总时数public: technician() { hourlyrate=150; } voidpay() { cout<<"输入当月总工作时数:"<<endl; cin>>workhours; salary=workhours*hourlyrate; } voiddisplay() { pay(); cout<<"兼职人员编号:"<<no<<"姓名:"<<name<<"本月工资"<<salary<<endl; }};classsalesman:virtualpublicemployee//定义销售人员类 {protected: floatcommrate;//提成比例 floatsales;//当月销售额public: salesman() { commrate=0.05; } voidpay() { cout<<"输入当月销售总额:"<<endl; cin>>sales;//输入当月销售额 salary=sales*commrate; } voiddisplay() { pay(); cout<<"销售人员编号:"<<no<<"姓名:"<<name<<"本月工资"<<salary<<endl; }};classmanager:virtualpublicemployee//定义经理类え {protected: floatmonthlypay;//月固定工资 public: manager() { monthlypay=10000; } voidpay() { salary=monthlypay; } voiddisplay() {pay(); cout<<"经理编号:"<<no<<"姓名:"<<name<<"本月工资"<<salary<<endl; }};classsalesmanager:publicmanager,publicsalesman//定义销售经理类 {public: salesmanager() { monthlypay=6000; commrate=0.01; } voidpay() { cout<<"输入当月销售总额:"<<endl; cin>>sales;//输入当月销售额 salary=monthlypay+sales*commrate; } voiddisplay() { pay(); cout<<"销售经理编号?:"<<no<<"姓名:"<<name<<"本月工资"<<salary<<endl; }};int_tmain(intargc,_TCHAR*argv[]){ techniciantechnician1; technician1.display(); salesmansalesman1; salesman1.display(); managermanager1; manager1.display(); salesmanagersalesmanager1; salesmanager1.display(); return0;}
习题6解答什么叫多态性?在C++中如何实现多态性?多态性(polymorphism)是面向对象程序设计的又一个重要特征,它是指不同对象接收到同一消息时会产生不同的行为。利用多态性可以设计和实现一个易于扩展的系统。C++中通过函数重载、运算符重载、虚函数实现多态性。什么叫静态联编?什么叫动态联编?二者有何区别?如果在编译程序时就能确定具体的调用对象,称为静态联编;如果在编译程序时还不能确定具体的调用对象,只有在程序运行过程中才能确定具体调用对象,称为动态联编。什么叫抽象类?抽象类有何作用?抽象类的派生类是否一定要给出纯虚函数的实现?如果一个类中至少有一个纯虚函数,这个类就是为抽象类,通常也称为抽象基类。它的主要作用是为一个类族提供统一的公共接口,使它们更有效地发挥多态性的特性。抽象类的派生类不一定要给出纯虚函数的实现。抽象类派生出新的类之后,如果派生类给出所有纯虚函数的函数实现,这个派生类就可以声明自己的对象,因而不再是抽象类;反之,如果派生类没有给出全部纯虚函数的实现,这时的派生类仍然是一个抽象类。4.编程题。(1)定义一个类B1具有虚函数vf()及非虚函数f(),函数分别输出字符串"B1::vf()"、"B1::f()"。将函数设为公有成员。设计一个类的对象调用这些函数。#include<iostream>usingnamespacestd;classB1{public:virtualvoidvf(){cout<<"B1::vf()"<<endl;}voidf(){cout<<"B1::f()"<<endl;}};voidmain(){B1b1;b1.vf();b1.f();getchar();}输出:B1::vf()B1::f()(2)定义B1的派生类D1,重写函数vf()。定义一个D1类的对象分别调用函数vf()、f()。#include<iostream>usingnamespacestd;classB1{public:virtualvoidvf(){cout<<"B1::vf()"<<endl;}voidf(){cout<<"B1::f()"<<endl;}};classD1:publicB1{public:virtualvoidvf(){cout<<"D1::vf()"<<endl;}};voidmain(){D1d1;d1.vf();d1.f();getchar();}输出:D1::vf()B1::f()(3)定义B1类的引用,用D1类的对象来初始化这个引用,通过该引用调用函数vf()、f()。#include<iostream>usingnamespacestd;classB1{public:virtualvoidvf(){cout<<"B1::vf()"<<endl;}voidf(){cout<<"B1::f()"<<endl;}};classD1:publicB1{public:virtualvoidvf(){cout<<"D1::vf()"<<endl;}};voidmain(){D1d1; B1&br=d1;br.vf();br.f();getchar();}输出:D1::vf()B1::f()(4)为类D1定义一个名为f()的函数,重复以上(1)、(2)、(3)练习。classD1:publicB1{public:virtualvoidvf(){cout<<"D1::vf()"<<endl;}voidf(){cout<<"D1::f()"<<endl;}};(5)在B1类中增加一个纯虚函数pvf(),重复以上(1)、(2)、(3)、(4)练习。classB1{public:virtualvoidvf(){cout<<"B1::vf()"<<endl;}voidf(){cout<<"B1::f()"<<endl;}virtualvoidpvf()=0;};(6)
为D1定义一个派生类D2,在D2中重写函数pvf(),创建一个D2类的对象调用函数f()、vf()、pvf()。#include<iostream>usingnamespacestd;classB1{public:virtualvoidvf(){cout<<"B1::vf()"<<endl;}voidf(){cout<<"B1::f()"<<endl;}virtualvoidpvf()=0;};classD1:publicB1{public:virtualvoidvf(){cout<<"D1::vf()"<<endl;}voidf(){cout<<"D1::f()"<<endl;}};classD2:publicD1{public:virtualvoidpvf(){cout<<"D2::pvf()"<<endl;}};voidmain(){D2d2;d2.f();d2.vf();d2.pvf();getchar();}(7)定义一个类B2具有纯虚函数pvf()。定义一个类D21具有字符串数据成员和重写的成员函数pvf();D21::pvf()输出字符串的值。定义一个类D22,与类D21不同之处是数据成员是整型。定义一个函数f(),参数为B2的引用B2&,在函数体中用该参数调用函数pvf()。主函数中用D21,D22的对象调用f()。#include<iostream>#include<string>usingnamespacestd;classB2{public:virtualvoidpvf()=0;};classD21:publicB2{public:strings1; D21(){s1="abcd";}virtualvoidpvf(){cout<<s1<<endl;}};classD22:publicB2{public:inti; D22(){i=100;}virtualvoidpvf(){cout<<i<<endl;}};voidf(B2&b2){b2.pvf();}voidmain(){D21d21;D22d22;f(d21);f(d22);getchar();}5.思考题。(1)定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。参加运算的两个运算符可以都是类对象,也可以其中有一个是整数,顺序任意。例如,c1+c2,i+c1,c1+i均合法(设i为整数,c1,c2为复数)。编程序,分别求两个复数之和、整数和复数之和。classComplex{public:Complex(){real=0;imag=0;}Complex(doubler,doublei){real=r;imag=i;}friendComple
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 采购物料追踪管理制度
- 临时物质采购领用制度
- 县残联采购管理制度
- 厂区采购日常管理制度
- 采购相关规章制度
- 一般采购部管理制度
- 学校油盐糖采购管理制度
- 原材料采购管控管理制度
- 日常行政采购制度
- 采购部降成本激励制度
- 2026广东深圳市优才人力资源有限公司公开招聘聘员(派遣至龙城街道)18人备考题库附答案详解(典型题)
- 2024-2025学年度哈尔滨传媒职业学院单招考试文化素质数学通关题库完美版附答案详解
- 第8章《力》单元测试卷(提升卷)(原卷版+解析)
- 克服压力(认知行为自助手册)
- 2024年02月苏州工业园区房地产交易管理中心2024年招考4名辅助人员笔试近6年高频考题难、易错点荟萃答案带详解附后
- 北京市部分地区2024届高三语文期初检测试卷汇编:文学类文本阅读()
- 中医护理操作并发症预防及处理
- 《大学生职业生涯规划与就业指导》(李新伟) 项目5
- 甲基丙二酸血症课件
- 工程测量 控制点交桩记录表
- GB/Z 41083-2021下肢矫形器的分类及通用技术条件
评论
0/150
提交评论