在上一课的指针和引用的源对象的基类,我们看一些例子,使用指针或引用基类必须简化代码的潜力。然而,在任何情况下,我们碰到的指针或引用只能调用一个函数库的版本问题,不是一个派生版本。
这里是一个简单的例子,这种行为:
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;
|