虚函数的类

你认为这一计划将输出?

让我们看看这个过程是如何。首先,我们实例化一个类的对象。rbase是一个指针,我们设置为指向的对象的一部分。最后,我们称rbase getname()。rbase getname()。计算结果为::getname()。然而,一个::getname()是虚拟的,所以编译器将检查所有A和C之间的类是否能找到一个更衍生得到的匹配。首先,它检查B::getname(),并找到一个匹配。然后检查C::getname()和找到一个更好的匹配。它不检查D::getname()因为我们原来的对象是一个C,不是一个D。因此,rbase。getname()解决C::getname()。

因此,我们的程序的输出:

rbase是C

一个更复杂的例子

让我们看看另一个动物的例子我们的工作与在上一课。这里的原始类:

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
34
35
36
37
38
39
40
#include <string>
class Animal
{
protected :
     std::string m_strName;
 
     // We're making this constructor protected because
     // we don't want people creating Animal objects directly,
     // but we still want derived classes to be able to use it.
     Animal(std::string strName)
         : m_strName(strName)
     {
     }
 
public :
     std::string GetName() { return m_strName; }
     const char * Speak() { return "???" ; }
};
 
class Cat: public Animal
{
public :
     Cat(std::string strName)
         : Animal(strName)
     {
     }
 
     const char * Speak() { return "Meow" ; }
};
 
class Dog: public Animal
{
public :
     Dog(std::string strName)
         : Animal(strName)
     {
     }
 
     const char * Speak() { return "Woof" ; }
};
这是 带虚函数的
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
34
35
36
37
38
39
40
#include <string>
class Animal
{
protected :
     std::string m_strName;
 
     // We're making this constructor protected because
     // we don't want people creating Animal objects directly,
     // but we still want derived classes to be able to use it.
     Animal(std::string strName)
         : m_strName(strName)
     {
     }
 
public :
     std::string GetName() { return m_strName; }
     virtual const char * Speak() { return "???" ; }
};
 
class Cat: public Animal
{
public :
     Cat(std::string strName)
         : Animal(strName)
     {
     }
 
     virtual const char * Speak() { return "Meow" ; }
};
 
class Dog: public Animal
{
public :
     Dog(std::string strName)
         : Animal(strName)
     {
     }
 
     virtual const char * Speak() { return "Woof" ; }
};

请注意,我们不做动物::getname()虚拟。这是因为getname()是从来没有在任何派生类中重写,因此没有必要。

现在,使用虚拟speak()功能,下面的功能应正常工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
void Report(Animal &rAnimal)
{
     cout << rAnimal.GetName() << " says " << rAnimal.Speak() << endl;
}
 
int main()
{
     Cat cCat( "Fred" );
     Dog cDog( "Garbo" );
 
     Report(cCat);
     Report(cDog);
}

事实上,这个程序产生的结果:

弗莱德说,喵

嘉宝说汪

当canimal。speak()评估程序,指出它是一个虚函数。在的情况下,ranimal指着一只猫的动物部分对象,程序会在所有的动物和猫之间的类是否能找到更多的衍生功能。在这种情况下,它发现猫::speak()。在的情况下,ranimal指出,狗的动物部分对象,程序解析函数的调用speak()狗:。

同样的,下面的数组的例子现在正常工作:

1
2
3
4
5
6
7
Cat cFred( "Fred" ), cTyson( "Tyson" ), cZeke( "Zeke" );
Dog cGarbo( "Garbo" ), cPooky( "Pooky" ), cTruffle( "Truffle" );
 
// Set up an array of pointers to animals, and set those pointers to our Cat and Dog objects
Animal *apcAnimals[] = { &cFred, &cGarbo, &cPooky, &cTruffle, &cTyson, &cZeke };
for ( int iii=0; iii < 6; iii++)
     cout << apcAnimals[iii]->GetName() << " says " << apcAnimals[iii]->Speak() << endl;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值