习题集1
判断题
1-1
对单目运算符重载为友元函数时,可以说明一个形参。而重载为成员函数时,不能显式说明形参。(T)
【解答】:回忆知识点,双目重载为友元2个形参,重载为成员1个形参(还有一个参数默认是this指针);单目重载为友元1个形参,重载为成员0个形参(一个参数默认是this指针)
1-2
虚函数是用virtual 关键字说明的成员函数。(T)
1-3
使用提取符(<<)可以输出各种基本数据类型的变量的值,也可以输出指针值。(T)
1-4
因为静态成员函数不能是虚函数,所以它们不能实现多态。(F)
1-5
重载operator+时,返回值的类型应当与形参类型一致。
比如以下程序中,operator+的返回值类型有错:
1 | class A { |
(F)
【解答】operator+的返回类型并不需要与参数类型一致。实际上operator+通常返回结果的类型可能与参数类型完全不同。
单选题
2-1
对象之间的相互作用和通信是通过消息。( )不是消息的组成部分。
A.接受消息的对象
B.要执行的函数的名字
C.要执行的函数的内部结构
D.函数需要的参数
2-2
( )不是面向对象程序设计的主要特征。
A.封装
B.继承
C.多态
D.结构
2-3
对定义重载函数的下列要求中,( )是错误的。
A.要求参数的个数不同
B.要求参数中至少有一个类型不同
C.要求函数的返回值不同
D.要求参数个数相同时,参数类型不同
2-4
关于动态绑定的下列描述中,( )是错误的。
A.动态绑定是以虚函数为基础的
B.动态绑定在运行时确定所调用的函数代码
C.动态绑定调用函数操作是通过指向对象的指针或对象引用来实现的
D.动态绑定是在编译时确定操作函数的
【解答】运行时确定的
2-5
关于虚函数的描述中,( )是正确的。
A.虚函数是一个static 类型的成员函数
B.虚函数是一个非成员函数
C.基类中说明了虚函数后,派生类中与其对应的函数可不必说明为虚函数
D.派生类的虚函数与基类的虚函数具有不同的参数个数和类型
【解答】虚函数是成员函数;基类的虚函数无论被公有继承多少次,在多级派生类中仍然为虚函数;派生类的虚函数与基类的虚函数具有相同的参数个数和类型
2-6
下列叙述中,不正确的是( )。
A.构造函数必须和类同名
B.构造函数和析构函数都没有返回值
C.析构函数中不能加代码
D.析构函数不能带参数
2-7
在下面类声明中,关于生成对象不正确的是( )。
1 | class point |
A.point p(10,2);
B.point *p=new point(1,2);
C.point *p=new point[2];
D.point *p[2]={new point(1,2), new point(3,4)};
2-8
下列运算符中,( )运算符不能重载。
A.&
B.[ ]
C.::
D.<<
2-9
关于纯虚函数和抽象类的描述中,( )是错误的。
A.纯虚函数是一种特殊的虚函数,它没有具体的实现
B.抽象类是指具有纯虚函数的类
C.一个基类中说明有纯虚函数,该基类的派生类一定不再是抽象类
D.抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出
【解答】纯虚函数是在声明虚函数时被“初始化”为0的虚函数。不定义对象而只作为一种基本类型作为继承的类,称为抽象类。凡是包含纯虚函数的类都是抽象类。抽象类的作用是作为一个类族的共同基类。
2-10
在下列关键字中,用以说明类中公有成员的是( )。
A.
public
B.private
C.protected
D.friend
程序填空题
5-2
CAT’s Copy
阅读下面的程序,完成其中复制构造函数的代码。
1 |
|
- 【解答】
itsAge = new int; // 分配新的内存空间*itsAge = *(c.itsAge); // 复制传入对象的itsAge的值
习题集2
填空题
1
write the output of the code below.
1 |
|
- 【解答】
- 1.
1 - 2.
3 - 3.
5
- 1.
2
write the output of the code below.
1 |
|
- 【解答】
- 1.
0 - 2.
0 - 3.
1 - 4.
1
- 1.
习题集3
填空题
1
write the output of the code below.
1 |
|
- 【解答】
10#21在
main函数中,定义了一个整数k并初始化为0然后,它调用函数
f,将k作为引用参数传入。在函数f中,参数i是对k的引用,所以i += 10;实际上是将k的值增加10。所以,k的值现在是10。函数f返回对k的引用,这个引用被赋给了mcout << k << "#";将输出10#接下来,
f(m)++再次调用了函数f,这次传入的是m,m实际上是对k的引用,所以i += 10;再次将k的值增加10,k的值现在是20。函数f返回对k的引用,然后++操作将k的值增加1,所以k的值现在是21- 高亮解释

- 高亮解释
最后,
cout << k << endl;将输出21
2
write the output of the code below.
1 |
|
- 【答案】
- 1.
*** - 2.
*** - 3.
*** - 4.
0 - 5.
1
- 1.
- 【解答】
- 最初a=0,++a进入
counter &counter::operator++()前置递增 - 第一次
++a,a=1,输出*** - 第二次
++a,a=2,输出*** - 第三次
++a后,a=3,输出*** - 第四次
++a,a=0,不进去 - a=0,输出0
- a++进入
int counter::operator++(int)后置递增 - 第一次
a++,while(a)中a=0不进去,然后a自增=1 - a=1,输出1
- 最初a=0,++a进入
3
1 |
|
- 输出
154- 自己算一下
习题集4
填空题
1
write the output of the code below.
1.the output at //1 is
2.the output at //2 is
3.the output at //3 is
4.the output at //4 is
5.the output at //5 is
1 |
|
- 【答案】
- 1.
1 - 2.
2 - 3.
7 - 4.
0 - 5.
0
- 1.
- 【解析】
- 注意第三题是7,length不包括
\0
- 注意第三题是7,length不包括
2
write the output of the code below.
1 |
|
- 【答案】
- 1.
dog! - 2.
dog! - 3.
pet!- 注意是纯虚函数不能实例化,虚函数是可以的!
- 1.
3
重复 过
4
write the output below
1 |
|
- 【答案】
- 1.
1 - 2.
2 - 3.
3 - 4.
11 - 5.
12
- 1.
5
重复,过
6
1 |
|
- 【解答】
- 1.
1 - 2.
0,2 - 3.
0
- 1.
- 【解析】
b.display()调用的是Base类的display()函数,因为b是Base类型的对象。Base类的display()函数会输出x的值,所以这行代码会输出1。d.display()调用的是Derived类的display()函数,因为d是Derived类型的对象。Derived类的display()函数会输出x和y的值。这里需要注意的是,尽管Derived类没有显式地初始化x,但是x会被Base类的构造函数初始化为0,而y会被Derived类的构造函数初始化为2。所以这行代码会输出0,2。Derived类的display()函数并没有被声明为override,并且它的函数签名与Base类的display()函数不同,因为它不是const函数。所以,实际上Derived类并没有重写Base类的display()函数,而是定义了一个新的display()函数。当p->display()被调用时,由于p是一个Base类型的指针,所以会调用Base类的display()函数,而不是Derived类的display()函数。Base类的display()函数会输出x的值,由于p指向的是Derived对象d,而d的x值在Derived的构造函数中并未被显式初始化,所以它的值是由Base的构造函数初始化的,为0。- 对第三行的错误解释(错的!):
p->display()调用的是Derived类的display()函数,因为p是一个指向Derived对象的Base类型的指针。C++中,当通过基类的指针或引用调用一个虚函数时,会根据指针或引用实际所指向的对象类型来决定调用哪个函数。
- 对第三行的错误解释(错的!):
- 【改编】
- 如果
virtual void display() { cout << x << endl; }改成virtual void display() const { cout << x << endl; }- 输出就是
1,0,2,0,2
- 输出就是
- 如果
void display() { cout << x << "," << y << endl; }改成void display() overide { cout << x << "," << y << endl; }- 输出就是
1,0,2,0,2
- 输出就是
- 如果同时改上面2个会报错
- 如果
习题集5
填空题
5
write the output of the code below.
1 |
|
- 【答案】
- 1.
2 - 2.
1
- 1.
- 【解答】
- 这段代码中,
C类包含了A类和B类的对象,以及一个int类型的变量。在main函数中,使用了C类对象之间的赋值操作m = n;。由于C类没有定义自己的赋值运算符operator=,所以编译器会为C类生成一个默认的赋值运算符。 - 默认的赋值运算符会按照成员在类中声明的顺序,依次调用每个成员的赋值运算符。在
C类中,成员的声明顺序是B b, A a, int c,所以在执行m = n;时,首先调用B类的赋值运算符,然后调用A类的赋值运算符,最后赋值int类型的成员。 B类的赋值运算符输出数字2,A类的赋值运算符输出数字1,所以程序的输出结果是2 1。而int类型的赋值操作不会产生输出,所以没有其他输出。
- 这段代码中,
6
write the output of the code below.
1 |
|
- 【答案】
- 1.
2 - 2.
1
- 1.


