调用引用上的虚函数 [英] Calling a virtual function on a reference

查看:144
本文介绍了调用引用上的虚函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下代码中,为什么 eat()对参考 c 的最后调用返回 动物b正在吃。 / em> ?根据我的理解, c 是对派生类 eat()的实例 b <虚函数。所以它应该已经返回狗狗b在吃。

In the following code, why does the last call of eat() on the reference c return "An animal b is eating." ? From my understanding, c is a reference to instance b of the derived class Dog and eat() is a virtual function. So it should have returned "A dog b is eating."

#include <string>
#include <iostream>

using namespace std;

class Animal
{

protected:
    string name;

public:
    Animal( string _name ):
    name(_name)
    {

    }

    virtual void eat()
    { 
        cout << "An animal " << name << " is eating." << endl;
    }
};

class Dog : public Animal
{

public:

    Dog( string _name ):
    Animal(_name)
    {

    }

    void eat()
    {
        cout << "A dog " << name << " is eating." << endl;
    }
};

int main( int argc , char ** argv )
{
    Animal a("A");
    a.eat();

    Dog b("b");
    b.eat();

    Animal & c = a;
    c.eat();

    c = b;
    c.eat();

    return 0;
}

这是输出:

An animal A is eating.

A dog b is eating. 

An animal A is eating. 

An animal b is eating.


推荐答案

为了利用动态多态性虚函数(在运行时区分派生类和基类),您需要通过基类指针或引用访问派生类对象。

In order to make use of the dynamic polymorphism provided by virtual functions (distinguishing between derived and base classes during runtime), you need to access the derived class object via the base class pointer or reference.

我已将您的代码注释掉可能发生的混乱:

I've commented out your code where confusion might have taken place:

int main( int argc , char ** argv )
{

    Animal a("A");
    a.eat();

    Dog b("b");
    b.eat();

    // Make a reference (alias) to Animal object and set it to the object a. 
    // From this point on, whenever you write c, think "a".
    Animal & c = a;
    // So, this is a.eat()
    c.eat();

    // This is a = b (Animal = Dog): DANGER! SLICING! Here, the assignment operator
    // slices the derived object and only assigns the base object "part" (remember, 
    // read "a", where you see "c" in your code): 
    // a.operator=(const A& b)
    c = b;
    // a.eat() = a is object of type A, so naturally, here you call A::eat()
    c.eat();

    return 0;
}

这篇关于调用引用上的虚函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆