1. ホーム
  2. c++

[解決済み] C++で仮想関数が必要な理由とは?

2022-03-04 01:08:03

質問

C++を勉強しているのですが、仮想関数に入ったところです。

私が読んだ限りでは(本やネットで)、仮想関数は基底クラスにある関数で、派生クラスでオーバーライドできるものだそうです。

しかし、この本の序盤、基本的な継承について学習する際に、派生クラスでベース関数をオーバーライドするために virtual .

では、ここで何が足りないのでしょうか?仮想関数にはもっと重要なことがあるのは知っていますし、重要なことのようなので、具体的にどんなことなのかはっきりさせたいと思っています。ただ、ネット上でわかりやすい答えが見つからないのです。

どのように解決するのですか?

を理解するだけでなく、どのように理解したかを説明します。 virtual というのは、この関数がなぜ必要なのか、ということです。

例えば、この2つのクラスがあるとします。

class Animal
{
    public:
        void eat() { std::cout << "I'm eating generic food."; }
};

class Cat : public Animal
{
    public:
        void eat() { std::cout << "I'm eating a rat."; }
};

メイン関数の中で

Animal *animal = new Animal;
Cat *cat = new Cat;

animal->eat(); // Outputs: "I'm eating generic food."
cat->eat();    // Outputs: "I'm eating a rat."

ここまでは良いのですが、どうでしょう?動物が一般的な食べ物を食べ、猫がネズミを食べる。 virtual .

では、少し変えてみましょう。 eat() は中間関数(この例では単なる些細な関数)を経由して呼び出されます。

// This can go at the top of the main.cpp file
void func(Animal *xyz) { xyz->eat(); }

さて、私たちのメイン関数は

Animal *animal = new Animal;
Cat *cat = new Cat;

func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating generic food."

あ、あぁ...Cat を func() しかし、ネズミは食べません。オーバーロードする場合は func() を取るので Cat* ? もし、Animalからさらに動物を派生させなければならないとしたら、それらはすべて独自の func() .

解決策としては eat() から Animal クラスに仮想関数を追加します。

class Animal
{
    public:
        virtual void eat() { std::cout << "I'm eating generic food."; }
};

class Cat : public Animal
{
    public:
        void eat() { std::cout << "I'm eating a rat."; }
};

メイン

func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating a rat."

完了です。