第一题第三题都是考察概念,看一下他们的区别:
编程题 #1
下面程序的输出结果是:
A::Fun
C::Do
请填空:
1234567891011121314151617181920212223242526272829303132#include <iostream>using namespace std ;class A {private :int nVal ;public :void Fun ( ){ cout << " A::Fun " << endl ; }void Do ( ){ cout << " A::Do " << endl ; }} ;class B : public A {public :virtual void Do ( ){ cout << " B::Do " << endl ; }} ;class C : public B {public :void Do ( ){ cout << " C::Do " << endl ; }void Fun ( ){ cout << " C::Fun " << endl ; }} ;void Call (// 在此处补充你的代码) {p . Fun ( ) ; p . Do ( ) ;}int main ( ) {C c ; Call ( c ) ;return 0 ;}
输入
无
输出
A::Fun
C::Do
编程题 #3
下面的程序输出结果是:
A::Fun
A::Do
A::Fun
C::Do
请填空:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include
<iostream>
using
namespace
std
;
class
A
{
private
:
int
nVal
;
public
:
void
Fun
(
)
{
cout
<<
"
A::Fun
"
<<
endl
;
}
virtual
void
Do
(
)
{
cout
<<
"
A::Do
"
<<
endl
;
}
}
;
class
B
:
public
A
{
public
:
virtual
void
Do
(
)
{
cout
<<
"
B::Do
"
<<
endl
;
}
}
;
class
C
:
public
B
{
public
:
void
Do
(
)
{
cout
<<
"
C::Do
"
<<
endl
;
}
void
Fun
(
)
{
cout
<<
"
C::Fun
"
<<
endl
;
}
}
;
void
Call
(
// 在此处补充你的代码
)
{
p
->
Fun
(
)
;
p
->
Do
(
)
;
}
int
main
(
)
{
Call
(
new
A
(
)
)
;
Call
(
new
C
(
)
)
;
return
0
;
}
输入
无
输出
A::Fun
A::Do
A::Fun
C::Do
***************************************************
答案分别为B&p;A * p
首先 ,都是通过多态实现的,所以传参的时候必须是引用或者指针,这个没问题,那么为什么第一题是B,第二题是A,而且是唯一答案呢?
第一题:填A..不行,因为A中do不是虚函数,所以不会调用C的do,会输出A..,A..
填C..不行,因为C重新定义了fun函数,所以会输出C..,C..
填B..ok,因为首先B没有写fun函数,所以会调用基类A的,其次B的do是虚函数,所以是多态,会调用指向的C,输出A..,C..
第二题:
填A..正确,因为A中do是虚函数,所以会调用C的do,会输出A..,C..
填C..不行,因为C重新定义了fun函数,所以会输出C..,C..,且C不能传入基类的参数
填B..不行,因为此题第一个实参是A*的对象,派生类不能被基类赋值,所以不行,如果去掉第一个实参,B是可以输出A..C..的
总结两题区别,第一题的基类A中的Do没有写成虚函数,所以不能填A&,第二题实参有A,注定了不可能填非A的,又因为A中do函数是虚函数,所以A*p正确。两题设计的特别巧妙,考察了多态和继承的一些概念。