1、 1 C+语言程序设计语言程序设计 期末考试试题及答案期末考试试题及答案 姓名 _ 学号 _ 班号 _ 题 号 一 二(1) 二(2) 三 总 分 成 绩 一、填空一、填空 1在类中必须声明成员函数的 原型 ,成员函数的 实现 部 分可以写在类外。 2如果需要在被调函数运行期间,改变主调函数中实参变量的值,则 函数的形参应该是 引用 类型或 指针 类型。 3 抽象 类只能作为基类使用,而不能声明它的对象。 4进行函数重载时,被重载的同名函数如果都没有用 const 修饰,则 它们的形参 个数 或 类型 必须不同。 5通过一个 常 对象只能调用它的常成员函数,不能调用其他成员 函数。 6函数的递
2、归调用是指函数直接或间接地调用 自身 。 7拷贝构造函数的形参必须是 本类对象的引用 。 2 二、阅读下列程序,写出其运行时的输出结果二、阅读下列程序,写出其运行时的输出结果 如果程序运行时会出现错误,请简要描述错误原因。 1 请在以下两题中任选一题, 该题得分即为本小题得分。如两题都答, 则取两题得分之平均值为本小题得分。 (1)程序: #include #include class Base private: char msg30; protected: int n; public: Base(char s,int m=0):n(m) strcpy(msg,s); void output(
3、void) coutListEmpty() la-DeleteAt(); else 第 8 页 共 109 页 lc-InsertRear(lb-Data(); lb-DeleteAt(); while ( !la-ListEmpty() ) lc-InsertRear(la-Data(); la-DeleteAt(); while ( !lb-ListEmpty() ) lc-InsertRear(lb-Data(); lb-DeleteAt(); int main() LinkedList la, lb, lc; int item, i; /读如数据建立链表 la for (i=0;i i
4、tem; la.InsertRear(item); la.Reset(); /读如数据建立链表 lb for (i=0;i item; lb.InsertRear(item); lb.Reset(); MergeList(/合并链表 lc.Reset(); / 输出各节点数据,直到链表尾 while(!lc.EndOfList() cout DisPoint(); delete p; return 0; 上面程序的输出结果为: 3若有以下程序: #include class Base public: 第 21 页 共 109 页 void Fun() cout = 1 ; i- ) for(
5、j = 1; j 1 5.友元关系不能( ) A.继承 B.是类与类的关系 C.是一个类的成员函数与另一个类的关系 D.提高程序的运行效率 6.语句ofstream f(SALARY.DAT,ios:appios:binary)的功能是建立流对象f,试图打开文 件SALARY.DAT 并与之连接,并且( ) A.若文件存在,将文件写指针定位于文件尾;若文件不存在,建立一个新文件 B.若文件存在,将其置为空文件;若文件不存在,打开失败 C.若文件存在,将文件写指针定位于文件首;若文件不存在,建立一个新文件 D.若文件存在,打开失败;若文件不存在,建立一个新文件 7.下面说法正确的是( ) A.内
6、联函数在运行时是将该函数的目标代码插入每个调用该函数的地方 B.内联函数在编译时是将该函数的目标代码插入每个调用该函数的地方 C.类的内联函数必须在类体内定义 D.类的内联函数必须在类体外通过加关键字inline 定义 8.可以用p.a 的形式访问派生类对象p 的基类成员a,其中a 是( ) A.私有继承的公有成员B.公有继承的私有成员 C.公有继承的保护成员D.公有继承的公有成员 9.在公有派生情况下,有关派生类对象和基类对象的关系,不正确的叙述是( ) A.派生类的对象可以赋给基类的对象 B.派生类的对象可以初始化基类的引用 C.派生类的对象可以直接访问基类中的成员 D.派生类的对象的地址
7、可以赋给指向基类的指针 10.对于类定义 class A public:virtual void func1( ) void func2( ) 第 56 页 共 109 页 class B:public A public:void func1( )cout是() pa-push(7075461); coutfilename; ifstream input(filename);/() coutnumber)/() outputnext = NULL; ; template void CLinkList:AppendNode( D data) Node * p = pHead; while( p-
8、next ) p = p-next; p-next = new Node; p-next-data = data; p-next-next = NULL; template void CLinkList:PrintList() Node * p; p = pHead-next; while( p ) cout Fun(); 第 95 页 共 109 页 pb-Print (); pd-Print (); pb = pb-Fun(); pb-Print(); /* D:Fun B:Fun D:Fun nBVal=2 nBVal=24 nDVal=8 B:Fun nBVal=12 */ 6)(4
9、分) class Base public: int val; Base() cout show(); 执行结果: A A A A 6-2 #include using namespace std; class A 第 102 页 共 109 页 public: virtual void show()coutshow(); 执行结果: B B C C 7全局对象在执行主函数前创建,静态对象只创建一次,他们均在程序结束时释放。 #include using namespace std; class name int a; public: name(int i)coutshow();r-show()
10、; p=q;p-show();p=r;p-show();q=r;r-show(); 执行结果: A B C B C C 10 #include using namespace std; class B int a; public: B(int i)a=i; void show()cout统称成员运算,均是左结合。 结构体成员可作为普通变量使用。 7.8 结构体成员的调用格式中有成员运算,因此,它参与运算(或操作)时,要适当加括号。 7.9 结构体成员可与普通变量、其它结构体的成员同名,也可与其上、下层结构体的成员同名。 7.10 元素为结构体的数组称作结构体数组, 以结构体为基类型的指针称作结
11、构体指针, 它们的定义和使用与普通 数组和普通指针基本相同。 7.11 共用体与结构体相似,主要区别有:定义共用体的保留字为 union;同一共用体数据中各成员的基址相 同,整体存储量为其成员的存储量之最大者。共用体中最后一次赋值的成员将覆盖之前赋值的所有成员,因此,只 有最后一次赋值的成员有意义。共用体变量初始化时,数据表中只有一个数据或数据表,它被赋给第一个成员。 7.12 定义枚举类型的一般语句格式和功能: 格式 enum 标识符枚举元素表变量表; 功能 指定枚举类型名,指定枚举元素的值,定义枚举型变量。第一个枚举元素的默认值为 0,其它枚举元素的 默认值为其前者加 1。 上述“标识符”
12、和枚举“变量表”可缺省。 7.13 枚举元素属只读变量,其值不可修改。 7.14 枚举型数据与 int 型兼容,存储量相同,但是,把 int 数据赋给枚举变量需强制转换类型。 7.15 typedef 语句的一般格式和功能为: 格式 typedef 数据类型名 别名表; 功能 给指定数据类型增加一组别名。 7.16 定义指针类型别名的格式为: 格式 typedef 类型名 *别名,*别名; 7.17 定义数据类型别名的格式为: 格式 typedef 元素类型名 别名第 1 维大小第 n 维大小,; 7.18 typedef 语句可在定义结构体、共同体、枚举类型的同时给它增加一组别名。 第 8
13、章 类和对象 8.1 面向对象程序设计方法可简单地定义为:以类为核心、以对象为基本操作单元、以消息传递为基本操作、具 有继承机制的程序设计方法。 8.2 面向对象中的对象是对具体客观事物的抽象,包括属性抽象和行为抽象两个方面。 8.3 属性是对象的静态特征,被抽象为成员变量,又称数据、数据结构等。 8.4 行为是对象的动态特征,被抽象为成员函数,又称操作、运算、功能、方法、算法等。 8.5 属性和行为是对象的两个要素, 对象是由其属性和行为组成的有机体。 把对象的数据(属性)和操作代码(行为) 第 105 页 共 109 页 封装成相对独立的基本单位称作封装或封装性。即,对象=数据结构+算法。
14、 8.6 类是具有相同属性和行为的一组对象的模板,是一组对象的共性之抽象。 8.7 定义类的一般语句格式和功能为: 格式 class 类名访问权限:成员变量和成员函数对象表; 功能 指定类名,指定类中成员及其访问权限。 8.8 类的成员访问权限分为三种: private: 私有的不对外(不可见)。 public: 公有的对外(可见)。 protected: 保护的仅对子类(可见)。 8.9 成员的默认访问权限是 private,新规定的访问权限取代之前的访问权限。 8.10 定义类的关键字 class 可改用 struct,后者规定,成员的默认访问权限是 public。 8.11 定义对象的一
15、般语句格式和功能为: 格式 类名 对象名(实参表或对象) 功能 创建指定对象,并初始化。 注意:省略全部实参时,要连同()一起省略。 8.12 由类创建对象称作类的实例化,对象又称类的实例。同类对象具有相同数据结构和操作。 8.13 类的成员可在类体外定义,但必须在类体中作相应声明,定义时必须在函数名前声明所在的类“类名:”, 此“:”称作作用域限定符。 8.14 类的成员函数只占一份存储空间,同类对象其享成员函数,对象只存储其成员变量。 8.15 访问对象中成员的一般格式为: 格式 对象名.公有成员变量名 格式 对象名.公有成员函数名(实参表) 格式 对象指针-公有成员变量名 格式 对象指针
16、-公有成员函数名(实参表) 8.16 在定义类时,其成员没有访问权限,均可访问。 8.17 在定义类时,当前对象的指针为 this,未被形参屏蔽的成员可省略前缀。 8.18 对象与外界交流信息又称传递消息,形式上表现为调用成员函数。 8.19 对象中的公用成员又称对外接口,只要接口不变,对类的内部修改不影响类外程序。 8.20 在定义类时,通常,把所有数据和不提供给外界使用的操作指定为私有的,使它们在外界只能被公有的操作 访问。这种做法称作信息隐蔽或隐蔽性。 第 9 章 关于类和对象的进一步讨论 9.1 构造函数是一个特殊成员函数。从形式上说,构造函数与类同名。从机制上说,构造函数在创建对象时
17、被自 动调用,通常用于初始化对象。 9.2 每个类都有其构造函数。无形参且函数体为空的构造函数可省略,此时称作隐式构造函数。 9.3 类中的成员变量不占内存,在定义类时,不允许给成员变量赋初值。 9.4 对象的初始化有以下几种格式: 格式一 类名 对象名=数据表 功能 把数据表中数据依次赋给对象的成员变量。 注意:此格式要求,成员变量均是公有的。 格式二 类名 对象名=对象 或 类名 对象名(对象) 功能 把右侧对象的成员变量依次赋给左侧对象的成员变量。 注意:此格式要求,右侧对象必须已存在,且与左侧对象属于同一类。 格式三 类名 对象名(初值表) 功能 以初值表为实参调用构造函数。 9.5
18、构造函数返回一个该类对象,其成员变量取构造函数结束时的值。但是,构造函数不允许定义返回值的类型, 不允许用带有返回值的 return 语句。 9.6 调用构造函数不允许加前缀(“对象.”或“对象指针-”)。构造函数应当定义为 public,除非该类不创建 对象。 9.7 定义构造函数可采用下述格式: 构造函数名(形参及类型、默认值表):成员变量(初值),成员变量(初值) 第 106 页 共 109 页 其中,成员变量不允许重复。 9.8 函数允许同名,称作函数的重载,它们的形参个数或类型必须有所区别,具体调用哪个函数由实参个数和类 型确定。构造函数也可重载。 9.9 允许指定函数形参的默认值,
19、调用时,未指定实参的对应形参取默认值。构造函数也如此。 9.10 构造函数的默认参数值必须在类体中指定。 9.11 声明带默认参数值的函数,可省略形参名。 9.12 调用带默认参数值的函数时,如果省略某个实参,则其后实参必须全省。因此,如果定义函数时,指定某个 形数的默认值,则必须指定其后所有形数的默认值。 9.13 析构函数是一个特殊成员函数。从形式上说,析构函数与类同名,另加前缀。从机制上说,析构函数在释 放对象时被自动调用,通常用于释放相应内存。 9.14 析构函数不允许定义返回值的类型,不允许用带有返回值的 return 语句。 9.15 析构函数应当定义为 public,除非该类不创
20、建对象。 9.16 析构函数的函数体为空时可省略,此时,称其为隐式或空析构函数。 9.17 析构函数没有形参,因此,不能重载析构函数,每个类只有一个析构函数。 9.18 通常,先创建的对象后释放,后创建的对象先释放,相当于把对象放在一个栈中。 9.19 全局和静态局部对象只创建一次,直到程序结束时才被释放。 9.20 关于对象数组有以下两条特殊规定: 必须指定数组中全部元素的默认值或初值。 用数据表给数组赋初值时,数据被依次赋给对象中的第一个成员变量。 9.21 关于对象指针有以下两条特殊规定: 动态申请单个对象要求指定默认值或初值。 申请多元动态数组要求指定默认值。 9.22 成员函数指针的
21、定义格式为:函数值类型 (类名:*指针变量)(形参类型表); 9.23 成员函数名不是函数指针,要加上取地址运算/类名和 const 可交换 功能 使该对象只能调用 const 成员函数,而且,除了被声明为 mutable 的成员变量外,不允许修改对象中的其 它成员变量。 9.28 常成员变量的初值必须在构造函数中用下述格式指定:常成员变量(初值表达式) 9.29 创建对象后,不允许修改常成员变量的值,它是具体对象中的常量,而非整个类的常量。 9.30 在声明和定义成员函数时,函数括号后均加上 const 者称作常成员函数。常成员函数只能修改被声明为 mutable 的成员变量,只能调用常成员
22、函数。 9.31 定义指针变量时,*和变量之间插入 const 者称作常指针变量,简称常指针。常指针必须在定义时给定其所 指向的目标,之后不允许修改(不允许再指向别处)。如果常指针所指向的目标不是常变量,则允许修改所指向的变量。 9.32 在基类型名前或后加上 const 所定义的指针变量称作指向常变量的指针。 指向常变量的指针所指向的目标未 必是常变量,但是,不允许用该指针去修改所指向的数据,因此,对于该指针来说,它指向的是“常变量”。 常指针不允许修改自身的值,常变量的指针不允许修改所指向的数据。 9.33 指向常变量的指针必须是常指针。 9.34 若实参是常变量,则对应的函数形参必须是常
23、变量。 9.35 动态建立对象(new) 格式 new 类名对象个数 格式 new 类名 格式 new 类名(初值表) 功能 申请所需连续内存;自动调用构造函数初始化对象;返回基址。 后两种格式均是申请 1 个对象的存储空间。 9.36 释放动态对象(delete) 格式 delete 对象的指针 格式 delete 对象的指针 功能 自动调用析构函数;释放对象。 第 107 页 共 109 页 9.37 若对象内申请了动态内存,则在析构函数中要有相应释放功能。 9.38 对象的赋值格式为:目标对象=源对象。 9.39 对象的复制格式为:目标对象(源对象) 9.40 对象的复制仅限于定义目标对
24、象时,即,用源对象初始化目标对象。 9.41 对象的赋值和复制是成员变量间的对应赋值,因此,成员变量的数据类型均要支持自身类型的赋值。 9.42 定义成员变量时,在类型名前或后加上 static 所定义的成员变量称作静态成员变量。 9.43 静态成员变量被该类对象所共享,只占一份内存,隶属于类,而非具体对象,即使未定义对象它也占内存。 9.44 静态成员变量在程序运行之初分配内存,直到程序结束时才被释放。 9.45 静态成员变量必须在类体外指定初值,格式为: 类型名 类名:静态成员变量=初值; 当初值为 0 时,可连同赋值号一起省略。 9.46 对于公有的静态成员变量的类外调用,除了用对象或对
25、象指针调用外,也可附加类名调用,格式为:类名: 静态成员变量 9.47 定义成员函数时,在函数前加上 static 所定义的成员函数称作静态成员函数。 9.48 静态成员函数没有默认的对象,不接收 this 指针,不能直接访问非静态成员。 9.49 对于公有的静态成员函数的类外调用,除了用对象或对象指针调用外,也可附加类名调用,格式为:类名: 静态成员函数(实参表) 9.50 友元分为友元函数和友元类,友元函数可以是普通函数和成员函数。声明友元的格式为: 声明友元函数 friend 函数声明; 声明友元类 friend class 类; 9.51 声明友元的语句必须在类体中,不区分权限。 9.
26、52 友元函数和友元类中的成员函数可访问指定它为友元的类中私有成员。 9.53 友元不具有对称性和传递性。 9.54 类模板的定义格式为:templateclass 类模板名类体; 9.55 类模板的调用格式和功能为: 格式 类模板名 功能 用实参对应替换类模板中的形参,得到具体的类。 9.56 在类模板体外定义成员函数的格式为: template函数类型 类模板名:函数定义 第 10 章 运算符重载 10.1 重载双目运算符的一般定义格式为: 返回值类型 operator 运算符(形参)函数体 其中,当前对象是运算的左目,形参是运算的右目,函数体是运算的具体操作。 10.2 对于重载后的双目
27、运算,使用格式为: 左目运算符右目 或 对象.operator 运算符(形参) 对象指针-operator 运算符(形参) 10.3 重载单目运算符的一般定义格式为:返回值类型 operator 运算符()函数体 其中,当前对象是运算的右目,函数体是运算的具体操作。 10.4 对于重载后的单目运算,使用格式为: 运算符右目 或 对象.operator 运算符() 对象指针-operator 运算符() 10.5 运算符重载要遵守以下规则: 只能重载已有的运算符。 不能重载的运算符有 5 个:“.”(成员运算)、“.*”(成员指针运算)、“:”(域运算)、“sizeof”(存储字 节运算)、“?
28、:”(条件运算符)。 另外,“-*”是一个双目运算符,可重载。 重载运算符不能改变其目数,因此,不能指定重载运算符形参的默认值,操作数的类型必须有所改变至少 有一个是类类型。 另外,重载不改变运算符的优先级和结合性,有些运算符只能重载为成员函数或友元函数。 第 108 页 共 109 页 10.6 重载右+和右-的定义格式为: 返回值类型 operator +(int)函数体 返回值类型 operator -(int)函数体 其中,int 是伪形参。 10.7 cin 是 istream 类对象,输入操作符又称流提取符,它从输入流 istream 提取数据。 10.8 cout 是 ostre
29、am 类对象,输出操作符(istream friend ostream 10.10 用单参数构造函数可实现其它类型数据到本类对象的转换,此构造函数的定义和调用格式为: 定义 构造函数(被转类型 形参)转换规则 调用 构造函数(被转数据) 10.11 把类的对象转换为基本类型需重载数据类型转换运算符(),只能重载为成员函数,定义格式为: operator 基本类型名()转换规则 第 11 章 继承与派生 11.1 继承又称派生,被继承者称作父类或基类,继承者称作子类或派生类。 11.2 派生类的定义格式为: class 派生类:继承方式 1 基类 1,继承方式 n 基类 n派生类新增成员变量和函
30、数; 11.3 父类的成员被子类继承后,成为子类的成员,这些成员称作派生成员。 11.4 派生类对象中派生成员变量的存储依照派生它的基类从左至右顺序存储,之后为派生类新增成员变量。 派生成员变量 新增成员变量 11.5 继承方式有三种 public、protected、private,其中,private 为默认继承方式。 11.6 从一个基类继承称作单继承,从多个基类继承称作多重继承。 11.7 派生成员的访问权限有四种:public、protected、private、不可访问。非派生成员只有前三种访问权限。 11.8 成员的类内和类外访问权限为: public private prote
31、cted 不可访 问 类内访 问 可 可 可 否 类外访 问 可 否 否 否 11.9 基类成员的访问权限和派生方式决定了派生成员的访问权限: 基类中访问权 限 公有派生 私 有 派 生 保护派生 private 不可访问 不 可 访 问 不可访问 public public private protected protected protected private protected 不可访问 不可访问 不 可 访 问 不可访问 11.10 关于成员的访问权限有下述等价定义: 公有成员类外可访问 不可访问成员类内不可访问 私有成员类内可访问,派生为不可访问。 保护成员类外不可访问,派生为可访
32、问。 11.11 派生类构造函数由两部分组成, 一是调用基类构造函数用于初始化继承部分, 二是初始化派生类新增部分。 派生类构造函数的一般形式为: 派生类名(完整形参表):基类名 1(实参表),基类名 n(实参表)派生类新增功能 对于指定了形参默认值的基类构造函数,基类实参表可以部分或全部省略,全部省略等效于连同“基类名()”一 起省略。 11.12 基类构造函数(体)在派生类构造函数(体)之前执行。 11.13 释放派生类对象时,基类析构函数在派生类析构函数之后自动执行,因此,派生类析构函数只需释放派生 第 109 页 共 109 页 类新增的动态内存,否则可能出错。 11.14 派生类也可
33、派生子类,形成多级派生。子类之下的派生(类)称作间接派生(类),父类之上的基类称作间接 父类。 11.15 当基类与基类或基类与派生类之间有同名成员时,会引起二义性(不包括重载成员函数),应加前缀“派生 它的基类名:”来区分,其中,派生类新增同名成员可省略此前缀。 11.16 在基类的派生方式前或后加上 virtual,则称它为派生类的虚基类,简称虚基类。 11.17 对于同一个类一直以虚基类派生成员,当它们被派生到同一个派生类时,只派生为一个成员,不重复派生。 11.18 如果虚基类的构造函数带参数, 而且没有指定默认参数值, 则其各级派生类均要调用这个虚基类构造函数。 11.19 基类对象
34、与子类对象有以下兼容规则: 子类对象(或指针)可以向父类对象(或指针)赋值、复制、传递函数参数。 基类对象可以引用派生类对象。 11.20 类中的成员变量可以是另一个类的对象,则称该对象是此类(对象)的子对象。含有子对象的类称作组合类 或复合类(对象中有对象)。 11.21 在组合类构造函数中,应当初始化子对象,组合类构造函数的一般格式为: 派生类名(完整形参表):,子对象(实参表), 第 12 章 多态性与虚函数 12.1 多态性是指:相同对象或不同对象收到相同消息会产生不同的行为(一个接口多种方法)。 12.2 简单地说,多态性是由成员同名引发,分为以下几种情况: 重载函数使得成员函数同名
35、。 从基类继承了同名成员。 派生类中重新定义了与基类同名的成员。 12.3 多态性分为静态多态性和动态多态性。 静态多态性在程序编译时就能确定调用哪个成员, 又称编译时多态性。 动态多态性则在程序运行中动态地确定调用哪个成员,又称运行时多态性。 12.4 附加 virtual 声明的成员函数称作虚函数。 12.5 虚函数使得,基类指针和引用可以调用各级派生类中新增的同名成员函数。虚函数及相关操作的要点如下: 在基类中定义与拟调用成员函数同名、参数个数和参数类型相同、返回值类型相同的虚函数。 用基类指针指向派生类对象,或基类对象引用派生类对象。 12.6 虚函数必须是成员函数,不可重载。 12.
36、7 static 成员函数不能声明为虚函数。 12.8 把构造函数声明为虚函数没有意义。 12.9 基类对象不能调用派生类新增成员函数 12.10 派生类继承基类的虚函数,派生类中屏蔽基类中虚函数者仍为虚函数。 12.11 如果基类的析构函数为虚函数,则派生类的析构函数也为虚函数。 12.12 如果为基类指针动态分配了派生类对象(组),则基类析构函数应声明为虚函数,否则,释放基类指针所指 向派生类对象时,只调用基类析构函数,不调用派生类析构函数。 12.13 没有函数体的虚函数称作纯虚函数。含有纯虚函数的类称作抽象类。 12.14 纯虚函数的一般定义格式: 返回值类型 virtual 函数名(形参表)=0; 12.15 纯虚函数没有函数体,不能调用,有别于函数体为空的虚函数。 12.16 纯虚函数被派生类继承为纯虚函数,屏蔽纯虚函数者不再是纯虚函数,变为普通虚函数。 12.17 抽象类不能创建对象,但是,可以定义抽象类指针。