C++笔试试题讲解(~~~可能是全站唯独一份有解析的~~~)
C++笔试题前言一、面向对象程序概论基本理论笔试题前言笔者整理了C++的笔试题,希望能在理论知识上帮到大家,解析为博主所作,若有问题,请私信博主或在评论区留言提示:以下是本篇文章正文内容,下面示例可供参考一、面向对象程序概论基本理论1.在结构化程序设计方法中,程序可表示为程序=数据结构+算法; 而面向对象的程序设计方法,程序可表示为程序=对象+消息。2. 结构化程序设计方法中的基本模块是过程;而面
C++笔试题讲解
前言
笔者整理了C++的笔试题,题目来源于《面向对象程序设计教程(C++语言描述)》------清华大学出版社,博主从里面挑选了部分试题(不包括程序分析类,有时间博主再单独编写),针对网上有很多关于此教材的答案,但是几乎没有博主愿意为其做解析,所以笔者利用闲余时间对一定题目进行了解析补充,博主希望能在理论知识上帮到大家,解析为博主所作,但由于时间仓促,难免会有问题,若有问题,请私信博主或在评论区留言,若能让大家有所收获,是笔者最大的荣幸!
一、面向对象程序概论
基本理论
1.在结构化程序设计方法中,程序可表示为程序=数据结构+算法; 而面向对象的程序设计方法,程序可表示为程序=对象+消息。
2. 结构化程序设计方法中的基本模块是过程;而面向对象程序设计方法中的基本模块是类。
3. 面向对象程序设计方法具有抽象性、封装性、继承性和多态性等特点。
笔试题
1.面向对象程序设计中,把对象的属性和行为组织在同一个模块内的机制叫做( C )。
A. 抽象 B. 继承 C. 封装 D. 多态
PS:抽象:我们知道对象都是通过类来描绘的,但是并不是所有的类都是用来描绘对象的, 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
继承: 继承是指一个对象直接使用另一对象的属性和方法。
多态:C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
2.在面向对象程序设计中,类通过( D )与外界发生关系。
A. 对象 B. 类 C. 消息 D. 接口
PS:类通过外部接口,与外界发生关系,对象与对象之间通过消息进行通讯。
3.下面( A )不是面向对象系统所包含的要素。
A. 重载 B. 对象 C. 类 D. 继承
PS:面向对象 =对象+类+继承+消息+多态
4.下面说法正确的是( BC )。
A. 将数据结构和算法置于同一个函数内,即为数据封装
B. 一个类通过继承可以获得另一个类的特性
C. 面向对象要求程序员集中于事物的本质特征,用抽象的观点看待程
D. 同一消息为不同的对象接受时,产生的行为是一样的,这称为一致性
PS:将数据结构和算法置于同一个类内, 即为数据封装。 同一消息为不同的对象接受时, 产生的行为可能是不一样的,这称为多态性
5 下面说法正确的是( AD )。
A. 对象是计算机内存中的一块区域,它可以存放代码和数据
B. 对象实际是功能相对独立的一段程序
C. 各个对象间的数据可以共享是对象的一大优点
D. 在面向对象的程序中,对象之间只能通过消息相互通信
PS:对象是计算机内存中的一块区域。在对象中,不但存有数据,而且存有代码,使得每个对象在功能上相互之间保持相对独立。 对象之间存在各种联系, 但它们之间只能通过消息进行通信。
6.在高级程序设计语言中, 一般用类来实现对象, 类是具有相同属性和行为的一组对象的集合,它是创建对象的模板 (T)
7.面向对象程序设计中的消息应该包含“如何做”的信息 (F)
PS:应该是做什么,对象根据信息决定如何做
8.一个消息只能产生特定的响应效果(F)
PS:一个消息可以产生不同的响应效果-----多态性
9.在 C++语言中,类是支持数据封装的工具(T)
10.C++语言和 Java 语言均不是一个纯正的面向对象的程序设计的语言。(F)
PS:JAVA是纯正的
二.从C到C++
基本理论
1.所谓引用就是给对象取一个别名, 使用该别名可以存取该对象。 换句话说是使新对象和原对象共用一个地址。
2.内联函数是使用 inline 关键字声明的函数。
3.重载函数指在同一个作用域内名字相同而参数不同的函数。
4.重载函数通常用来对具有相似行为而数据类型或数据个数不同的操作提供—个通用的名称。
5.指针的值是它所指向那个对象的地址值。指针的类型是它所指向对象的类型。指针的内容便是它所指向对象的值
6.C++ 有值传递和引用传递两种参数传递机制
7.运算符 new用于进行动态内存分配, 运算符 delete 用于释放动态分配的内存。
8.下面程序的输出结果为
笔试题
1.
PS:类型 *指针名,*指针名
2.若有定义“ double xx=3.14 ,*pp=&xx; ”,则 *pp 等价于(D)
A.&xx B.*xx C.3.14 D.xx
PS:pp 指向 xx 所在的内存单元,这样 *pp 和 xx 等价
3.下面对引用的描述中( C )是错误的。
A. 引用是某个变量或对象的别名
B. 建立引用时,要对它初始化
C. 对引用初始化可以使用任意类型的变量
D. 引用与其代表的对象具有相同的地址
PS : 所谓引用就是给对象取一个别名, 使用该别名可以存取该对象, 所以对引用初始化必须使用同类型的变量。
4.对重载的函数来说,下面叙述不正确的是( D )。
A. 参数的类型不同
B. 参数的顺序不同
C. 参数的个数不同
D. 参数的个数、类型、顺序都相同,但函数的返回值类型不同
PS:对重载的函数来说,编译系统将根据函数参数的类型和个数来判断使用哪一个函数,所以重载函数参数的个数、类型、顺序不能都相同
5.下列有关设置函数参数默认值的描述中,( D )是正确的。
A. 对设置函数参数默认值的顺序没有任何规定
B. 函数具有一个参数时不能设置默认值
C. 默认参数要设置在函数的原型中,而不能设置在函数的定义语句中
D. 设置默认参数可使用表达式,但表达式中不可用局部变量
PS:若没有声明函数原型, 参数的默认值可在函数定义的头部进行设置, 否则必须在函数原型中进行设置。
在一个指定了默认值的参数右边不能出现没有指定默认值的参数。
6.下面说法正确的是( C )。
A. 所有的函数都可以说明为内联函数
B. 具有循环语句、 switch 语句的函数不能说明为内联函数
C. 使用内联函数,可以加快程序执行的速度,但会增加程序代码的大小
D. 使用内联函数,可以减小程序代码大小,但使程序执行的速度减慢
PS:内联函数主要是解决程序的运行效率问题。 在程序编译时, 编译系统将程序中出现内联函数调用的地方用函数体进行替换, 进而减少了程序运行的时间, 但会增加程序代码的大小。 它是以空间换取时间, 因此内联函数适用于功能不太复杂,但要求被频繁调用的函数
7.使用 const 说明常量时,可以不必指出类型 (F)
PS:如果用 const 定义的是一个整型常量,则类型说明符 int 可以省略
8 引用被创建时可以用任意变量进行初始化 (F)
PS:必须为同类型变量
9.一个返回引用的调用函数可以作为左值 (T)
10.函数可以没有参数,也可以没有返回值(T)
11没有参数的两个函数是不能重载的(T)
12.函数可设置默认参数, 但不允许将一个函数的所有参数都设置为默认参数(F)
PS:函数可设置默认参数,且允许将一个函数的所有参数都设置为默认参数
三.类与对象
基本理论
1.类定义中关键字 private 、public 和 protected 以后的成员的访问权限分别是私有、公有和保护。如果没有使用关键字,则所有成员默认定义为 private权限。具有 public 访问权限的数据成员才能被不属于该类的函数所直接访问.
2.定义成员函数时,运算符“∷”是作用域运算符,“ MyClass∷”用于表明其后的成员函数是在“ MyClass 类”中说明的
3.在程序运行时,通过为对象分配内存来创建对象。在创建对象时,使用类作为样板,故称对象为类的实例。
4 .假定 Dc 是一个类,则执行“ Dc a[10],b(2)”语句时,系统自动调用该类构造函数的次数为 (11)
PS:创建 10 个数组元素需调用构造函数 10 次,创建对象 b 需调用构造函数 1次,所以系统自动调用该类构造函数的总次数为 11
5.对于任意一个类,析构函数的个数最多为 1 个
6.delete 运算符通常用于实现释放该类对象中指针成员所指向的动态存储空间的任务
7.C++ 程序的内存格局通常分为 4 个区: 数据区、代码区、栈区和堆区
8.数据定义为全局变量,破坏了数据的 封装性; 较好的解决办法是将所
要共享的数据定义为类的静态成员。
9.友元函数和友元类统称为友元
10.静态数据成员和静态成员函数可由任意访问权限许可的函数访问
11.友元的正确使用能提高程序的效率,但破坏了类的封装性和数据的隐蔽性。
12.若需要把一个类 A定义为一个类 B的友元类,则应在类 B的定义中加入一条语句: friend class A
笔试题
1.有关类的说法不正确的是( BC )。
A. 类是一种用户自定义的数据类型
B. 只有类的成员函数才能访问类的私有数据成员
C. 在类中,如不做权限说明,所有的数据成员都是公有的
D. 在类中,如不做权限说明,所有的数据成员都是私有的
PS:类是一种用户自定义的数据类型,类中成员均具有一种访问权限。关键字public 、protected 和 private 以后的成员的访问权限分别是公有、 保护和私有的,所有成员默认定义为 private 的。私有成员是被隐藏的数据,只有该类的成员函数或友元函数才可以访问它
2 关于类和对象的说法( C )是错误的。
A. 对象是类的一个实例
B. 任何一个对象只能属于一个具体的类
C. 一个类只能有一个对象
D. 类与对象的关系和数据类型与变量的关系相似
PS:任何一个对象只能属于一个具体的类, 但一个类可以有多个对象。
3 设 MClass 是一个类, dd 是它的一个对象, pp 是指向 dd 的指针,cc 是 dd的引用,则对成员的访问, 对象 dd 可以通过( B )进行,指针 pp 可以通过( D )进行,引用 cc 可以通过( B )进行。
A ∷ B . C & D ->
4.关于成员函数的说法中不正确的是( C )。
A. 成员函数可以无返回值
B. 成员函数可以重载
C. 成员函数一定是内联函数
D. 成员函数可以设定参数的默认值
PS:与普通函数不同的是,成员函数是属于某个类的。 成员函数的实现, 可以放在类体内,也可以放在类体外。在类体外实现的成员函数不再是内联函数
5.下面对构造函数的不正确描述是( B )。
A. 系统可以提供默认的构造函数
B. 构造函数可以有参数,所以也可以有返回值
C. 构造函数可以重载
D. 构造函数可以设置默认参数
PS:构造函数不能指定返回类型, 即使是 void 类型也不可以。
6.假定 A是一个类,那么执行语句“ A a,b(3),*p; ”调用了( B )次构造函数。
A. 1 B. 2 C. 3 D. 4
PS:声明指针是不会调用构造函数的
7.下面对析构函数的正确描述是( AC )。
A. 系统可以提供默认的析构函数
B. 析构函数必须由用户定义
C. 析构函数没有参数
D. 析构函数可以设置默认参数
PS:析构函数的作用是在对象消失时执行一项清理任务。 如果一个类中没有定义析构函数, 系统将自动生成一个默认析构函数。 析构函数没有参数, 当然不可能设置默认参数。
8.类的析构函数是( D )时被调用的。
A. 类创建 B. 创建对象 C. 引用对象 D. 释放对象
9.创建一个类的对象时,系统自动调用( B ); 撤销对象时,系统自动
调用( C )。
A. 成员函数 B. 构造函数 C. 析构函数 D. 复制构造函数
10.通常拷贝构造函数的参数是( C )。
A. 某个对象名 B. 某个对象的成员名
C. 某个对象的引用名 D. 某个对象的指针名
11.关于 this 指针的说法正确的是( B )。
A. this 指针必须显式说明 B. 当创建一个对象后, this 指针就指向该对象
C. 成员函数拥有 this 指针 D. 静态成员函数拥有 this 指针。
PS: this 指针是由 C++编译器自动产生且较常用的一个隐含对象指针, 它不能被显式声明。当创建一个对象时, this 指针就初始化指向该对象。但只有非静态成员函数才拥有 this 指针,并通过该指针来处理对象。
12.下列关于子对象的描述中,( B )是错误的。
A. 子对象是类的一种数据成员,它是另一个类的对象
B. 子对象可以是自身类的对象
C. 对子对象的初始化要包含在该类的构造函数中
D. 一个类中能含有多个子对象作其成员
PS:子对象不可以是自身类的对象,如果一个类的成员是自身类对象,会形成嵌套定义
13 对 new运算符的下列描述中,( B )是错误的。
A. 它可以动态创建对象和对象数组
B. 用它创建对象数组时必须指定初始值
C. 用它创建对象时要调用构造函数
D. 用它创建的对象数组可以使用运算符 delete 来一次释放
PS:使用运算符 new创建对象数组的格式如下:
new < 类型说明符 > [<算术表达式 >]
其中,<算术表达式 >给出数组的大小, 后面不能再跟构造函数参数, 所以用它创建对象数组时不能指定初始值。
14.对 delete 运算符的下列描述中,( D )是错误的。
A. 用它可以释放用 new运算符创建的对象和对象数组
B. 用它释放一个对象时,它作用于一个 new所返回的指针
C. 用它释放一个对象数组时,它作用的指针名前须加下标运算符[ ]
D. 用它可一次释放用 new运算符创建的多个对象
PS:用 delete 一次只能释放用 new创建的 1 个对象,但可释放一个对象数组。
15.关于静态数据成员,下面叙述不正确的是( C )。
A.使用静态数据成员,实际上是为了消除全局变量
B.可以使用“对象名 . 静态成员”或者“类名∷静态成员”来访问静态数据成员
C.静态数据成员只能在静态成员函数中引用
D.所有对象的静态数据成员占用同一内存单元
PS:静态数据成员可以在静态成员函数中引用,也可以在非静态成员函数中引用。
16.对静态数据成员的不正确描述是( CD )。
A. 静态成员不属于对象,是类的共享成员
B. 静态数据成员要在类外定义和初始化
C. 调用静态成员函数时要通过类或对象激活, 所以静态成员函数拥有 this 指针
D. 只有静态成员函数可以操作静态数据成员
PS:this 指针是一个局部量,局部于某个对象,而静态成员函数是属于整个类
而不是某个对象,它没有 this 指针。静态成员函数和非静态成员函数均可操作静态数据成员。
17 下面的选项中,静态成员函数不能直接访问的是( D )。
A. 静态数据成员 B. 静态成员函数
C. 类以外的函数和数据 D. 非静态数据成员
PS:由于静态成员函数没有 this 指针,它只能直接访问该类的静态数据成员、静态成员函数和类以外的函数和数据, 访问类中的非静态数据成员必须通过参数传递方式得到对象名,然后通过对象名来访问。
18 在类的定义中,引入友元的原因是( A )。
A. 提高效率 B. 深化使用类的封装性
C. 提高程序的可读性 D. 提高数据的隐蔽性
PS:友元的作用主要是为了提高效率和方便编程
19.友元类的声明方法是( A )。
A. friend class< 类名>; B. youyuan class< 类名>;
C. class friend< 类名>; D. friends class< 类名>;
20.下面对友元的错误描述是( D )。
A. 关键字 friend 用于声明友元
B. 一个类中的成员函数可以是另一个类的友元
C. 友元函数访问对象的成员不受访问特性影响
D. 友元函数通过 this 指针访问对象成员
PS:友元函数是一个放在类中的普通函数,它没有 this 指针。
21.下面选项中,( C )不是类的成员函数。
A. 构造函数 B. 析构函数 C. 友元函数 D. 拷贝构造函数
PS:友元函数不是成员函数,它是类的朋友,因而可以访问类的全部成员
简答
1.什么是 this 指针?它的主要作用是什么
答:this 指针是 C++语言为成员函数提供的一个隐含对象指针, 它不能被显式声明。this 指针是一个局部量,局部于某个对象。不同的对象调用同一个成员函数时,编译器根据 this 指针来确定应该引用哪一个对象的数据成员
2.什么叫做拷贝构造函数?拷贝构造函数何时被调用?
答:拷贝构造函数是一种特殊的构造函数, 它的作用是用一个已经存在的对象去初始化另一个对象。为了保证所引用的对象不被修改,通常把引用参数声明为const 参数。
在以下 3 种情况下,拷贝构造函数都会被自动调用:
1当用类的一个对象去初始化该类的另一个对象时;
2当函数的形参是类的对象,进行形参和实参结合时;
3当函数的返回值是类的对象,函数执行完成返回调用者时
四.继承机制
基本理论
1 如 果 类 A 继 承 了 类 B , 那 么 类 A 被 称 为 派 生 类 , 而 类 B 被 称 为 基 类 。
2.C+ + 的 两 种 继 承 为 : 单 继 承 和 多 继 承 。
3.在 默 认 情 况 下 的 继 承 方 式 为 私 有 继 承 方 式 。
4. 从 基 类 中 公 有 派 生 一 个 类 时 , 基 类 的 公 有 成 员 就 成 为 派 生 类 的 公 有 成 员 , 而 这 个 基 类 的 保 护 成 员 就 成 为 派 生 类 的 保 护 成 员 。
5.C+ + 提 供 了 多 继 承 的 机 制 , 允 许 一 个 派 生 类 可 以 继 承 多 个 基 类 , 甚 至 这 些 基 类 是 互 不 相 关 的 。
6. 类 X中 的 名 字 N 支 配 类 Y 中 同 名 的 名 字 N , 是 指 类 X以 类 Y 为 它 的 一 个 基 类 , 这 称 为 支 配 规 则 。
7.引 进 虚 基 类 的 目 的 是 解 决 二 义 性 问 题 。
8. 在 一 个 继 承 结 构 中 , 解 决 二 义 性 的 方 法 有 使 用 作 域 运 算 符 和 引进 虚 基 类 。
笔试题
1.继承是(CD )的方法。
A.将特殊的类变成通用的类
B.将通用的参数传递给特殊的类的对象
C.将通用的类变成特殊的类
D.将已有的类添加新的特征,但不重新写它们
2.继 承 的 优 点 是 ( ABC ) 。
A. 扩 大 类 的 使 用 范 围 , 更 便 于 使 用 类 库
B 避 免 重 写 程 序 代 码 , 提 供 有 库 的 概 念 框 架
C 把类 转 化 成 有 条 理 的 层 次 结 构
D. 通过继 承的自然选择和重写使类进一步拓展
3下面叙述不正确的是( C )。
A.基类的保护成员在保护派生类中仍然是保护的
B.基类的保护成员在公有派生类中仍然是保护的
C.基类的保护成员在私有派生类中仍然是保护的
D.对基类的保护成员的访问必须是无二义性的
PS:基类的保护成员在私有派生类中是私有的
4.派生类的对象对它的基类成员中( A )是可以访问的。
A.公有继承的公有成员
B.公有继承的私有成员
C.公有继承的保护成员
D.私有继承的公有成员
PS:只要是派生类,都可以丛基类中继承,除非把基类的构造函数定义为私有的,这样派生类无法构造
5.( C )是可以访问类对象的私有数据成员的。
A.该类的对象
B.该类友元类派生的成员函数
C.类中的友元函数
D.公有派生类的成员函数
6.多继承是( B )。
A.多个单继承的叠加
B.派生类有多个直接基类
C.多个派生类有唯一的基类
D.每个派生类最多只有一个直接基类,但它可以有多个间接基类
PS:一个派生类有多个基类
7.关于多继承二义性的描述,( D )是错误的。
A.派生类的多个基类中存在同名成员时,派生类对这个成员访向可能出现二义性
B.由于二义性原因,一个类不能从同一个类中一次以上直接继承
C.使用作用域运算符对成员进行限制可以解决二义性
D.派生类和它的基类中出现同名函数时,派生类对这个成员函数的访问可能出现二义性
PS:在多继承的场景里,当父类中存在同名变量时,子类访问父类的同名变量,将出现二义性,因为编译器不知道你将要访问的是哪个父类中的变量。
派生类和它的基类中出现同名函数时,派生类对这个成员函数的访问绝不可能出现二义性
8 .作用域运算符通常用来( AD )。
A.指定特定的类
B.指明从哪一个基类中导出来的
C.在某些成员函数中限定静态变量的可视范围
D.解决二义性
PS:两个独立的类, 则互访时候, 只能是静态函数,可以通过 :: 访问。如果 是继承关系, 则 静态非静态都可以。
9.多继承派生类析构函数释放对象时,( A )被最先调用。
A.派生类自己的析构函数
B.基类的析构函数
C.根基类的析构函数
D.派生类中子对象类的析构函数
10增加一个基类的派生类,需要对基类进行根本改变。(F)
PS:比如c类是由a类派生的,但现在,又要用到b类, 想把b也作为c的基类,那么c:a,c:b,c:a: b即可
11.如果没有为派生类指定构造函数,则派生类的对象会调用基类的构造函数。(T)
12.对一个类来说,可能的访问权限为: private.public.protected 和不可访问。(F)
PS:无不可访问
13.无论哪种派生方式,基类中的私有成员在派生类中都是不可访问的。(T)
14.在派生过程中,派生类继承包括构造函数和析构函数在内的所有基类成员。(F)
PS:不是所有的函数都能自动从基类中继承到派生类中
15.在单继承中,派生类对象对基类成员函数的访问也可能出现二义性。(F)
PS:单继承是一个派生类只在一个基类里继承某个部分,二义性只能在多继承里面。
简答题
1.简述在继承方式下创建派生类对象时,构造函数调用顺序,以及删除派生类对象时派生类析构函数的调用顺序。
答:创建派生类对象时构造函数调用顺序:首先调用基类构造函数,子对象所在类构造函数次之,最后执行派生类构造函数。
删除派生类对象时派生类析构函数的调用顺序:先调用派生类的析构函数;再调用派生类中子对象类的析构函数;再调用普通基类的析构函数;最后调用虚基类的析构函数。
2.简述在 3 种继承方式下基类成员的访问权限。
答:当类的继承方式为公有继承时,在派生类中,基类的公有成员和保护成员被继承后分别作为派生类的公有成员和保护成员,这样使得派生类的成员函数可以直接访问它们,而派生类的成员函数无法直接访问基类的私有成员。 在类外部,派生类的对象可以访问继承下来的基类公有成员。
当类的继承方式为私有继承时,在派生类中,基类的公有成员和保护成员作为派生类的私有成员,派生类的成员函数可以直接访问它们,而派生类的成员函数无法直接访问基类的私有成员。在类外部,派生类的对象无法访问基类的所有成员。
当类的继承方式为保护继承时,在派生类中,基类的公有成员和保护成员作为派生类的保护成员,派生类的成员函数可以直接访问它们,而派生类的成员函数无法直接访问基类的私有成员。在类外部,派生类的对象无法基类的所有成员
五.多态性和虚函数
基本理论
1.C++的两种联编方式为:静态 联编和 动态 联编。
2.C++支持两种多态性,静态联编所支持的多态性被称为 编译时的多态性 、 动态联编所支持的多态性被称为 运行时的多态性
3.重载函数在编译时表现出多态性,就是 静态 联编;而虚函数则在运行时表现出多态性是 动态 联编。
4.为了区分重载函数,把一个派生类中重定义基类的虚函数称为 覆盖 。
5.如果派生类与基类的虚函数仅仅返回类型不同,其余相同,则C++认为是 使用不恰当的虚函数。
6.在构造函数和析构函数中调用虚函数时,采用 静态 联编。
7.纯虚函数的定义是在虚函数定义的基础上,再让函数等于 0 。
8.对于包含有纯虚函数的类被称为 抽象类
笔试题
1.在C++中,要实现动态联编,必须使用( D )调用虚函数。
A. 类名
B. 派生类指针
C. 对象名
D. 基类指针
2.下列函数中,可以作为虚函数的是( BD )。
A. 普通函数
B. 非静态成员函数
C. 构造函数
D. 析构函数
PS:不可以定义为虚函数的函数:1.普通函数。2.友元函数。3.静态成员函数。 4.构造函数;拷贝构造函数
3.在派生类中,重载一个虚函数时,要求函数名、参数的个数、参数的类型、参数的顺序和函数的返回值( B )。
A. 不同
B. 相同
C. 相容
D. 部分相同
4.使用虚函数保证了在通过一个基类类型的指针(含引用)调用一个虚函数时,C++系统对该调用进行( A ),但是,在通过一个对象访问一个虚函数时,使用( B )。
A. 动态联编
B. 静态联编
C. 动态编译
D. 静态编译
PS:动态联编必须包括以下方面:成员函数必须申明为virtual
如果基类中申明了为虚函数,则派生类中不必再申明。
调用方式:
通过对象的指针或引用调用成员函数;或通过成员函数调用
静态联编室在于编译时候完成
5.下面函数原型声明中,( B )声明的func()为纯虚函数。
A. void func()=0;
B. virtual void func()=0;
C. vitual void func();
D. virtual void func(){};
6.若一个类中含有纯虚函数,则该类称为( C )。
A. 基类
B. 虚基类
C. 抽象类
D. 派生类
7.假设Myclass为抽象类,下列声明( CD )是错误的。
A. Myclass& func(int);
B. Myclass * pp;
C. int func(Myclass);
D. Myclass Obj;
PS:C.不可作为参数类型
D.不可以作为返回值类型
8.下面描述中,( BD )是正确的。
A. 虚函数是没有实现的函数
B. 纯虚函数的实现是在派生类中定义
C. 抽象类是只有纯虚函数的类
D. 抽象类指针可以指向不同的派生类
9.抽象类中只能有一个纯虚数。( F )
PS:最少有一个
10.构造函数和析构函数都不能说明为虚基数。 ( F)
PS:析构函数是可以写成虚函数的,由于虚函数的地址是要写在虚函数表中的,而虚函数表的地址是记录在虚函数指针vfptr当中的,vfptr一般情况都部署在对象的前4个字节,因此,一个成员方法/函数能不能实现成虚函数,需要两点:
1.对象已经存在了
2.函数得有地址
像构造函数,inline成员函数,static成员函数等都不能定义成virtual函数
11.程序中可以说明抽象类的指针或引用.( T )
12.一个类中的虚基数说明不仅对基类中的同名函数有影响,而且对它的派生类中的重定义的函数也有影响。 ( F )
PS:一个类中的虚函数说明只对派生类中重定义的函数有影响,对它的基类中的函数并没有影响
13.在构造函数和析构函数中调用虚函数时,采用动态联编,即它们所调用的虚函数时是在派生类中重定义的虚函数。 ( F )
PS:析构函数中调用虚函数采用静态联编
14.因为没有为纯虚函数定义代码,所以在构造函数和析构函数内均不可调用纯虚函数。 ( T )
简答题
1虚函数与一般重载函数有哪些区别?
答:虚函数与一般重载函数的区别,主要有以下几点:
重载函数只要求函数有相同的函数名,并且重载函数是在相同作用域中定义的名字相同的不同函数。而虚函数不仅要求函数名相同,而且要求函数的签名、返回类型也相同。也就是说函数原型必须完全相同,而且虚函数特性必须是体现在基类和派生类的类层次结构中。
重载函数可以是成员函数或友元函数,而虚函数只能是非静态成员函数。
构造函数可以重载,析构函数不能重载。正好相反,构造函数不能定义为虚函数,析构函数能定义为虚函数。
重载函数的调用是以所传递参数序列的差别作为调用不同函数的依据,而虚函数是根据对象的不同去调用不同类的虚函数。
重载函数在编译时表现出多态性,是静态联编;而虚函数则在运行时表现出多态性是动态联编。
2.什么叫做抽象类?抽象类有何作用?抽象类的派生类是否一定要给出纯虚函数的实现?
答:一个类可以说明多个纯虚函数,对于包含有纯虚函数的类被称为抽象。抽象类用来描述一组子类的共同的操作接口,它用作基类。抽象类的派生类不一定要给出纯虚函数的实现。如果没有在派生类中给出纯虚函数的实现,则需在派生类中仍将它说明为纯虚函数,否则编译器将给出错误信息。说明了纯虚函数的派生类仍是抽象类。
六.运算符重载
基本理论
(1)运算符的重载实际上是 函数 的重载。
(2)运算符函数必须被重载为 非静态成员函数 或被重载为 友元函数 。
(3)成员函数重载运算符需要的参数的个数总比它的操作数 少 一个。
(4)重载赋值运算符时,通常返回调用该运算符的 对象的引用 ,这样赋值就能进行连续赋值操作。
(5)重载“[ ]”函数必须且只能带 1 个形参,且规定其参数的类型为 整型。
(6)重载调用运算符函数可以带有 多 个参数
笔试题
1.下列运算符中,不能被重载的是(B)。
A. [ ] B. ● C. ( ) D. /
PS:不能被重载的运算符
2.下列描述重载运算符的规则中,不正确的是(C)。
A. 重载运算符必须符合语言语法 B. 不能创建新的运算符
C. 不能改变运算符操作的类型 D. 不能改变运算符原有的优先级
PS:是可以改变运算符的操作类型的,比如笔者举个例子,1+1=2,你可以自己定义运算规则,比如1只羊驼+1只羊驼=1顿烤全羊(哈哈,皮一下很开心)
3.下列运算符中,不能有友元函数重载的是(A)。
A. = B.> C. < D. <>
PS:赋值运算符只能重载为成员运算符函数,不能重载为友元运算符函数
= , ( ) , [ ] 和 -> 都不能被友元重载
4.下列描述中,不正确的是(C)。
A. 赋值运算符有时也需要重载
B. 在重载增量或减量运算符时,若应用友元函数,则需要使用引用参数
C. 在任何情况下,重载运算符既可用友元函数,也可用成员函数
D. 若在某自定义类中重载了下标运算符“[ ]”,则可将该类的类对象当作一个“数组”
PS: 赋值运算符不能作为成员函数
5.下标运算符的重载提供了在C++中实现安全的数组下标的一种方法。 ( T )
6.对下标运算符“[ ]”,即可重载为类成员函数,又可重载为友元函数。 ( F )
PS:= , ( ) , [ ] 和 -> 都不能被友元重载
7.重载后缀“++”运算符时多给出的一个int参数,在函数体中并不被使用。( T)
8.重载运算符需要的参数个数与操作数一样多。 ( F )
PS:比如笔者举个栗子(笔者觉得自己已经没有举起栗子的力气了~~~)定义一个重载二元加,Complex operator + (Complex c); 这里只有一个参数,在主函数里我们求两个数的和,Complex c1(1,1),c2(1,1); Complex c;
可得c=c1+c2;这里的操作数为2,所以两者不一定数目相同。
简答题
1.重载前缀“++”运算符与重载后缀“++”运算符在形式上有什么不同?
答:重载后缀运算符带有形参int而重载前缀运算符没有。
以成员函数方式重载前缀“++”运算符的函数原型的一般格式如下:
<返回类型>::operator++();
以类成员方式重载后缀“++”运算符的函数原型的一般格式如下:
<返回类型>::operator++(int);
以友元函数方式重载前缀“++”运算符的函数原型格式如下:
<返回类型>::operator++(<类名>&);
以友元方式重载后缀“++”运算符的函数原型格式如下:
<返回类型>::operator++(<类名>&,int);
2.赋值运算符重载与拷贝构造函数有什么区别?
答:拷贝构造函数和赋值运算符重载函数都是用来拷贝一个类的对象给另一个同类型的对象。要注意拷贝构造函数与赋值运算符重载函数的使用区别。
①拷贝构造函数是用已存在对象的各成员的当前值来创建一个相同的新对象。在下述3种情况下,系统将自动调用所属类的拷贝构造函数:
当说明新的类的对象的同时,要给它赋值另一个已存在对象的各成员当前值。
当对象作为函数的赋值参数而对函数进行调用要进行实参和形参的结合时。
当函数的返回值是类的对象,在函数调用结束后返回到主调函数处。
②赋值运算符重载函数要把一个已存在对象的各成员当前值赋值给另一个已存在的同类对象。
3.比较两种运算符重载形式。
答:在许多情况下,用友元函数还是成员函数重载运算符在功能上没有什么区别;
有时将二元运算符重载为友元函数比重载为成员函数使用起来方便 。
当然,重载为友元函数也有一些限制。
第一,为保持与C++中规定的赋值语义相一致,虽然赋值运算符是个二元操作符,但不能重载为友元函数。
同样,也应将“+=”、“-=”等赋值运算符重载为成员函数。
第二,友元函数不能重载“()”、“[ ]”和“->”运算符。
第三,在重载增量或减量运算符时,若使用友元函数,则需要应用引用参数。
七.模板
基本理论
名词解析
函数模板:一个带类属参数的函数。
类模板:一个带类属参数的类。
模板函数 :通过参数实例化可以再构造出具体的函数。
模板类:通过参数实例化可以再构造出具体的类。
基本知识
1.C++支持两种模板,一种是 函数模板 ,另一种是 类模板 。
2.关键字 template 是定义模板的关键字。
3.<模板参数>中包含一个或多个用逗号分开的模板参数项,每一项由保留字 class 或者 typename 开始。
4.重载函数模板便于定义 类属参数 或者函数参数的类型、个数不相同所进行的 类似 操作。
5.函数模板实例化时, 没有 普通传值参数的类型转换机制。
6.STL提供的容器是常用数据结构的 类模板 。
7.STL容器类库包含7种基本容器。他们可以分成两组: 顺序容器 和 关联容器 。
8.STL迭代器主要包括5种基本类别: 输入迭代器 、 输出迭代器 、 前向迭代器 、 双向迭代器 、 随机访问迭代器 。
笔试题
1.关于函数模板,描述错误的是(A)
A、函数模板必须由程序员实例化为可执行的模板函数
B、模板函数的实例化有编辑器实现
C、一个类定义中,只要有一个函数模板,则这个类是类模板
D、类模板的成员函数都是函数模板,类模板实例化后,成员函数也随之实例化
2.下列模板说明中,正确的是(A)
A、template<typename T1,typename T2>
B、template<class T1,T2>
C、template(class T1,class T2)
D、template(typename T1 ,T2)
3.假设有函数模板定义如下:
template
Max(T a,T b, T&c)
{c=a+b;}
下列选项正确的是(AB)
A.float x ,y ;float z;
Max(x ,y ,z);
B、int x,y,z;
Max(x,y,z);
C、int x,y;float z;
Max(x,y,z);
D、float x; double y ,z;
Max(x,y,z);
4.建立类模板对象的实例化过程为(C)
A、基类 ——>派生类
B、构造函数——>对象
C、模板类——>对象
D、模板类——>模板函数
5.下面(ABD)是标准模板库中的主要组件。
A、容器 B、迭代器 C、文件 D、算法
6.一个模板函数能够被相同函数名的另外模板函数重载。 (T )
7.作为模板类型参数的关键字class,特别含义是“任何用户定义类的类型”。 ( F)
PS:class与类定义无任何关系
8.在类模板<模板参数表>中,必须至少有一个类参数。 ( T)
9.在类模板<模板参数表>中,可以使用函数类型参数,该参数与普通函数参数的用法和功效完全相同。 ( F)
PS:题干中加粗部分错误,只限于int, * , &可使用,float不可使用
10.迭代器就是我们平常所用的指针。 ( F)
八.I/O流类库
基本理论
1.在C++的输入输出系统中,最核心的对象是 流(stream) 。执行输入和输出操作的类体系叫做 流 类 。
2.当实际进行I/O操作是,cin与 标准输入设备相关联。
3.C++的流类库预定了4个流,它们是 cin 、 cout 、 cerr 和 clog。
4.使用文件流类库的程序必须用#include编译指令文件将头文件 fstream.h包含起来。
5.C++的I/O流类库提供了2种控制格式输入输出的方法。一种是用 ios类的成员函数,另一种是 控制符。
6.按数据的存取方式来分类,文件可分为 顺序文件 和 随机读写文件 。
7.C++中共有3种文件流,它们是 输入文件流 、 输出文件流 和 输入/输出文件流 。
8.打开文件就是使一个文件流对象与 一个指定的文件 相关联。
9.如果打开文件失败,则流对象的值为 0 。
10.最好用istream的函数 read 和ostream的函数 write 分别来读/写二进制文件。
笔试题
1.进行文件输入操作时应包含(B)文件
A. ifstream.h B.fstream.h C.ofstream.h D.iostream.h
2.下列类中( A )不是输人输出流类iostream的基类。
A. fstream B. istream C. ostream D.ios
3.在下列选项中( B C D )是ostream类的对象。
A. cin B. cerr C. clog D. cout
4.使用控制符进行格式输出时,应包含( C )文件。
A. iostream. h B. math. h
C. iomanip. h D. fstream. h
5.在ios类提供的控制格式标志字中,( A )是转换为十六进制形式的标志常量。
A. hex B. oct C. dec D. right
6.下列选项中,用于清除基数格式位设置以八进制输出的语句是( C )。
A. cout< <setf(ios:.dec ,ios:basefield);
B. cout< <setf(ios::hex,iosbasefield);
C. cout< < setf(iosl.octios…; basefield);
D. cin>>setf(ios::hex,ios::basefield);
7.函数setf(a,ios::adjustifiled)中a的值可以是( A B )。
A. ios::left B. ios::right C. ios::hec D. ios::oct
8.下列格式控制符,在iostream. h中定义的是( A D ),在iomanip.b中定义的是( B C )。
A. endl B. setfill C. setw D. oct
9.控制输出格式的控制符中,( D )是设置输出宽度的。
A. ws B. ends C. sefill() D. setw()
10.下列输出字符’A’的方法中,( B )是错误的。
A. cout<<‘A’; B. cout<<put(‘A’);
C. coul. put(‘A’); D. char a=‘A’; cout< < a;
11.关于对getline()函数的下列描述中,( A )是错误的。
A.该函数所使用的终止符只能是换行符
B.该函数是从键盘上读取字符审的
C.该函数所读取的字符串的长度是受限制的
D. 该函数读取字符审时遇到终止符便停止
12 下面( B C )语句能把"Hello,students"赋值给一个字符数组string[50]。
A. cin> > string; B. cin. getline(string ,80);
C. cin, get(string,40,’\n’); D. cin. get(string);
13.关于read()函数的下列描述中,( C )是正确的。
A.该函数只能从键盘输人中获取字符串
B.该函数只能用于文本文件的操作
C.该函数只能按规定读取指定数目的字符
D.从输人流中读取一行字符
14.在打开磁盘文件的访问方式常量中,( C )是以追加方式打开文件的。
A. in B. out C. app D. ate
15.下面( B C D )语句以写的方式打开文件“myfile. dat”。
A. ifstream infile( “myfile. dat” ,ios::in);
B. fstream infile(“myfile. dat” ,ios::app);
C. fstream infile( “myfile. dat” ,ios::out);
D. ofstream infile( “myfile. dat”);
16.假定已定义整型变量data,以二进制方式把data的值写人输出文件流对象outile中去,正确的语句是( C )。
A. outfile. write((int* )&data ,sizeof(int));
B. outfile. write((int* )&data,data);
C. outfile. write( (char* )&data ,sizeof(int));
D. outfile, write((char* )&data,data);
17.流格式标志字的每位表示一种格式,格式位之间互不影响。 (F)
18.控制符本身是一一种对象,它可以直接被提取符或插人符操作。 (T)
19.预定义的提取符和插人符都是可以重载的。 (T)
20.函数write()是用来将一个字符串送到一种输出流中,但必须将一个字符串中全部字符都送到输出流中。 (F)
PS:函数原型:ostream&write (const char * pch,int nCount);
把nCount个字符从pch所指的缓冲区写入输出流。
21.以app方式打开文件时,当前指针定位于文件尾。 (T)
22 read()函数只能用于文本文件的操作中。 (F)
PS:read()函数用于将从指定文件描述符中读出的数据放到缓存区中,并返回实际读入的字节数,read()的缓存这一缓存指的是应用程序自己开辟的缓存区。
九.异常处理(第九章试题暂时未做解析)
基本理论
1.运行异常,可以 预料 ,但不能避免,它是由 系统运行环境 造成的。
2.在小型程序开发中,一旦发生异常所采取的方法一般是 将程序立即中断运行,从而无条件释放所有资源 。
3.C++的异常处理机制使得异常的引发和处理 不必 在同一函数中。
4.如果预料某段程序(或对某个函数的调用)有可能发生异常,就将它放在 try语句 中。
5.如果某段程序中发现了自己不能处理的异常,就可以使用throw<表达式>抛掷这个异常,其中的<表达式>表示异常类型。
6.如果异常类型声明是一个省略号(…),catch子句便处理 任何 类型的异常,这段处理程序必须catch块的最后一段处理程序。
7.异常接口声明也称 抛出列表 ,已经成为函数界面的一部分。
8.函数圆形的抛出列表是一个空表,表示该函数 不抛出 任何类型的异常。
9.在异常处理程序中发现异常,可以在 catch 语句中用throw语句抛出。
笔试题
1.处理异常用到3个保留字,除了try以外,还有(AC)
A. catch B. class C. throw D. return
2.catch(…)一般放在其它catch子句的后面,子句的作用是(B)
A.抛掷异常 B.捕获所有类型的异常 C.检测并处理异常 D.有语法错误
3.关于异常的描述中,错误的是(D)
A.异常既可以被硬件引发,又可以被软件引发
B.运行异常可以预料,但不能避免,它是由系统运行环境造成的
C.异常是指从发生问题的代码区域传递到处理问题的代码区域的一个对象
D.在运行程序中,一旦发生异常。程序立即中断运行
4.下列说法中错误的是(CD)
A.引发异常后,首先在引发异常的函数内部运行好异常处理过程
B.抛出异常是没有任何危险的
C.“抛出异常”和“捕捉异常”两种操作最好放在同一个函数中
D.异常处理过程在处理完异常后,可以通过带有参数的throw继续传播异常
5 try与catch总是结合使用的。(T)
6.一个异常可以是除类以外的任何类型。(F)
7.抛出异常后一定要马上终止程序。(F)
8.异常接口定义的异常参数表为空,表示可以引发任何类型的异常。(F)
9.C++标准库中不需要异常类,因为C++标准库中很少发生异常。(F)
10.异常处理程序捕获到异常后,必须马上处理。(F)
11.一个异常只能在catch语句中再用throw语句抛出。(F)
12.当catch子句的异常类型声明参数被初始化后,从对应try块开始到异常被抛那处之间构造(且尚未析构)的所有自动对象进行析构.(T)
笔者才疏学浅,请各位师傅不吝赐教,若是发现文章有写的有误的地方,请告知笔者,笔者会在第一时间进行修改。因笔者个人能力和时间的原因,暂时没有对所有题目进行解析,也没有收录全部题目,笔者只收录了自己认为比较重要的题目,还请各位读者谅解
文章很长,将近两万字,笔者在文中藏了几个小彩蛋,希望能缓解读者阅读时的压力,你的三连是对笔者最好的回报,博主不求打赏,点赞!收藏!评论!就是对笔者最大的肯定,谢谢大家!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)