在上一课的指针和引用的源对象的基类,我们看一些例子,使用指针或引用基类必须简化代码的潜力。然而,在任何情况下,我们碰到的指针或引用只能调用一个函数库的版本问题,不是一个派生版本。
这里是一个简单的例子,这种行为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class
Base { protected : public : const
char *
GetName() { return
"Base" ;
} }; class
Derived: public
Base { public : const
char *
GetName() { return
"Derived" ;
} }; int
main() { Derived
cDerived; Base
&rBase = cDerived; cout
<< "rBase
is a "
<< rBase.GetName() << endl; } |
这个例子打印结果:
rbase是基础
因为rbase是基类指针,它调用库::getname(),即使它的实际指向派生类对象的基部。
在本课中,我们将解决这个问题,使用虚拟函数。
虚拟函数
虚函数是一种特殊类型的函数,解决最派生版本的函数具有相同的签名。做一个虚函数,只需将“虚拟”的关键词在函数声明。
请注意,虚拟函数和虚基类的类是两个完全不同的概念,尽管它们共享相同的关键词。
这是上面的例子与虚函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class
Base { protected : public : virtual
const
char *
GetName() { return
"Base" ;
} }; class
Derived: public
Base { public : virtual
const
char *
GetName() { return
"Derived" ;
} }; int
main() { Derived
cDerived; Base
&rBase = &cDerived; cout
<< "rBase
is a "
<< rBase.GetName() << endl; return
0; } |
这个例子打印结果:
rbase是派生
因为rbase是一个指向派生类对象时,基部rbase。getname()评价,它通常会解决基地::getname()。然而,基地::getname()是虚拟的,它告诉程序去看看是否有任何更多的衍生版本的功能。由于基础对象,rbase指着实际上是派生类对象的一部分,该程序将检查每一个继承的类的基类和派生使用派生版本的函数,它发现之间。在这种情况下,导出getname():!
让我们以一个更复杂的例子,看一看:
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
|
class
A { public : virtual
const
char *
GetName() { return
"A" ;
} }; class
B: public
A { public : virtual
const
char *
GetName() { return
"B" ;
} }; class
C: public
B { public : virtual
const
char *
GetName() { return
"C" ;
} }; class
D: public
C { public : virtual
const
char *
GetName() { return
"D" ;
} }; int
main() { C
cClass; A
&rBase = cClass; cout
<< "rBase
is a "
<< rBase.GetName() << endl; |