4

私は仮想関数を理解しようとしていました。

次のコードを検討してください。

#include <iostream>
#include <memory>
#include <vector>

class Animal 
{
public:
     virtual void eat() 
    {
        std::cout << "I eat like a generic animal.\n";
    }

};

class Wolf : public Animal 
{
public:
    void eat() 
    {
        std::cout << "I eat like a wolf!\n";
    }
};


int main() 
{

  Animal      a;
  Wolf        w;

  a.eat();
  w.eat();

}

virtualキーワードを使用すると、出力が得られます

I eat like a generic animal.
I eat like a wolf!

必要に応じて。

しかし、仮想キーワードを削除しても、同じ出力が得られます。仮想関数の初歩的な理解から、私なしでvirtual出力を取得する必要がありました

I eat like a generic animal.
I eat like a generic animal.

ここに欠けている初歩的なものはありますか?

Linuxでg++コンパイラを使用しています

4

3 に答える 3

5

いいえ、それは正しい行動です。ポリモーフィズムを導入するには、仮想関数が必要です。ポリモーフの動作を有効にするには、次のようなポインターを使用する必要があります。

 Animal * a = new Animal();
 Animal * w = new Wolf();

 a->eat();
 w->eat();

 <...>

 delete a;
 delete w;

両方の変数が明らかに異なる型を持っているため、現在の方法では動作は正しいです。

于 2012-07-16T17:53:32.270 に答える
4

ポリモーフィズムは、インスタンスが実際に参照するオブジェクトのタイプを識別することによって機能します。

あなたの場合、実際の動物は次のとおりです。

Animal      a;  //a is an animal.
Wolf        w;  //w is a wolf.

したがって、ポリモーフィズムをまったく使用していません。

あなたがする必要があるのは、次のようなものです:

//Create a couple animal pointers.
Animal* a;
Animal* b;

//Create an animal instance and have a point to it.
a = new Animal();

//Create a wolf instance and have b point to it.
b = new Wolf();

//Calls Animal::eat as a is an animal.
a->eat();

//Calls Wolf::eat as a is a wolf.
b->eat();

このポリモーフィズムの使用を実現するために、ポインターまたは参照を使用できることに注意してください。

そのため、クラス型を操作するときは通常、オブジェクトを const 参照で渡す必要があります。

//Will call Animal::eat or Wolf::eat depending on what animal was created as.
void foo(const Animal& animal) {
    animal.eat();
}

//Will always call Animal::eat and never Wolf::eat since this isn't a reference or
//a pointer.  Will also "slice" a Wolf object.
void foo(Animal animal) {
    animal.eat();
}

スライスとは、より派生したクラス (オオカミ) をそのクラス (動物) の派生度の低いコピーに無差別に変換することを意味することに注意してください。

于 2012-07-16T17:59:27.197 に答える
1

仮想がなくても、それはまだ方法です。virtual キーワードは、次のような場合にポリモーフィックな動作を許可します。

Animal* wolf = new Wolf; // I eat like a wolf! (as long as eating is virtual)

virtual キーワードを使用することで、派生型に基づいて実行時に呼び出す適切な実装を選択するようコンパイラに指示します。

于 2012-07-16T17:56:34.877 に答える