1

次のコードで、参照cに対するeat()の最後の呼び出しが「動物 b が食べています。 」を返すのはなぜですか? 私の理解では、cは派生クラスDogのインスタンスbへの参照であり、eat()は仮想関数です。ですから、 「犬 b が食べています」と返されたはずです。

#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.
4

5 に答える 5

1

仮想関数によって提供される動的ポリモーフィズム (実行時に派生クラスと基本クラスを区別する) を利用するには、基本クラスのポインターまたは参照を介して派生クラス オブジェクトにアクセスする必要があります。

混乱が生じた可能性のあるコードをコメントアウトしました。

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;
}
于 2013-05-19T14:17:20.320 に答える