工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> C言語

C++ 仮想関数

C++ 仮想関数

このチュートリアルでは、例を使用して C++ 仮想関数とその使用法について学習します。

仮想関数は、派生クラスで再定義することが期待される基本クラスのメンバー関数です。

基本的に、関数が確実にオーバーライドされるようにするために、基本クラスで仮想関数が使用されます。 .これは、基本クラスのポインターが派生クラスのオブジェクトを指す場合に特に当てはまります。

たとえば、以下のコードを考えてみましょう:

class Base {
   public:
    void print() {
        // code
    }
};

class Derived : public Base {
   public:
    void print() {
        // code
    }
};

後で、Base のポインターを作成すると、 Derived のオブジェクトを指す型 クラスを作成して print() を呼び出します 関数、それは print() を呼び出します Base の機能 クラス。

つまり、Base のメンバー関数 はオーバーライドされません。

int main() {
    Derived derived1;
    Base* base1 = &derived1;

    // calls function of Base class
    base1->print();

    return 0;
}

これを避けるために、print() を宣言します。 Base の機能 virtual を使用してクラスを仮想として キーワード。

class Base {
   public:
    virtual void print() {
        // code
    }
};

仮想関数は、C++ におけるポリモーフィズムの不可欠な部分です。詳細については、C++ ポリモーフィズムに関するチュートリアルをご覧ください。


例 1:C++ 仮想関数

#include <iostream>
using namespace std;

class Base {
   public:
    virtual void print() {
        cout << "Base Function" << endl;
    }
};

class Derived : public Base {
   public:
    void print() {
        cout << "Derived Function" << endl;
    }
};

int main() {
    Derived derived1;

    // pointer of Base type that points to derived1
    Base* base1 = &derived1;

    // calls member function of Derived class
    base1->print();

    return 0;
}

出力

Derived Function

ここでは、print() を宣言しています。 Base の関数 virtual として .

したがって、Base のポインターを使用する場合でも、この関数はオーバーライドされます。 Derived を指す型 オブジェクト派生1 .

<図>

C++ オーバーライド識別子

C++ 11 では、新しい識別子 override が提供されました これは、仮想関数の使用中にバグを回避するのに非常に役立ちます。

この識別子は、基本クラスのメンバー関数をオーバーライドする派生クラスのメンバー関数を指定します。

たとえば、

class Base {
   public:
    virtual void print() {
        // code
    }
};

class Derived : public Base {
   public:
    void print() override {
        // code
    }
};

Derived で関数プロトタイプを使用する場合 クラスを作成し、その関数をクラス外で定義する場合は、次のコードを使用します:

class Derived : public Base {
   public:
    // function prototype
    void print() override;
};

// function definition
void Derived::print() {
    // code
}

C++ オーバーライドの使用

仮想関数を使用する場合、派生クラスのメンバー関数を宣言する際に間違いを犯す可能性があります。

override の使用 identifier は、これらの誤りが発生した場合にコンパイラにエラー メッセージを表示するように促します。

それ以外の場合、プログラムは単純にコンパイルされますが、仮想関数はオーバーライドされません。

考えられる間違いの例:


C++ 仮想関数の使用

基本クラス Animal があるとします および派生クラス DogCat .

各クラスに type という名前のデータ メンバーがあるとします。 .これらの変数がそれぞれのコンストラクターによって初期化されるとします。

class Animal {
   private:
    string type;
    ... .. ...
    public:
      Animal(): type("Animal") {}
    ... .. ...
};

class Dog : public Animal {
   private:
    string type;
    ... .. ...
    public:
      Animal(): type("Dog") {}
    ... .. ...
};

class Cat : public Animal {
   private:
    string type;
      ... .. ...
    public:
      Animal(): type("Cat") {}
    ... .. ...
};

ここで、プログラムで 2 つの public を作成する必要があるとします。 各クラスの関数:

<オール>
  • getType() type の値を返す
  • print() type の値を出力します
  • これらの両方の関数を各クラスで別々に作成してオーバーライドすることもできますが、これは長くて面倒です。

    または getType() にすることもできます バーチャル Animal で クラスを作成してから、単一の個別の print() を作成します Animal のポインタを受け取る関数 type を引数として使用します。次に、この単一の関数を使用して仮想関数をオーバーライドできます。

    class Animal {
        ... .. ...
       public:
        ... .. ...
        virtual string getType {...}
    };
    
    ... .. ...
    ... .. ...
    
    void print(Animal* ani) {
        cout << "Animal: " << ani->getType() << endl;
    }

    これにより、コードが短くなります。 、クリーナー繰り返しが少ない .


    例 2:C++ 仮想関数のデモ

    // C++ program to demonstrate the use of virtual function
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Animal {
       private:
        string type;
    
       public:
        // constructor to initialize type
        Animal() : type("Animal") {}
    
        // declare virtual function
        virtual string getType() {
            return type;
        }
    };
    
    class Dog : public Animal {
       private:
        string type;
    
       public:
        // constructor to initialize type
        Dog() : type("Dog") {}
    
        string getType() override {
            return type;
        }
    };
    
    class Cat : public Animal {
       private:
        string type;
    
       public:
        // constructor to initialize type
        Cat() : type("Cat") {}
    
        string getType() override {
            return type;
        }
    };
    
    void print(Animal* ani) {
        cout << "Animal: " << ani->getType() << endl;
    }
    
    int main() {
        Animal* animal1 = new Animal();
        Animal* dog1 = new Dog();
        Animal* cat1 = new Cat();
    
        print(animal1);
        print(dog1);
        print(cat1);
    
        return 0;
    }

    出力

    Animal: Animal
    Animal: Dog
    Animal: Cat

    ここでは、仮想関数 getType() を使用しました。 そして Animal ポインター ani print() の繰り返しを避けるために すべてのクラスで機能します。

    void print(Animal* ani) {
        cout << "Animal: " << ani->getType() << endl;
    }

    main() で 、3 つの Animal を作成しました Animal のオブジェクトを動的に作成するポインタ 、 DogCat クラス。

    // dynamically create objects using Animal pointers
    Animal* animal1 = new Animal();
    Animal* dog1 = new Dog();
    Animal* cat1 = new Cat();

    次に print() を呼び出します これらのポインターを使用する関数:

    <オール>
  • print(animal1)の場合 が呼び出されると、ポインタは Animal を指します 物体。 Animal の仮想関数 クラスは print() 内で実行されます .
  • print(dog1)の場合 が呼び出されると、ポインタは Dog を指します 物体。したがって、仮想関数がオーバーライドされ、Dog の関数が print() 内で実行されます .
  • print(cat1)の場合 が呼び出されると、ポインタは Cat を指します 物体。したがって、仮想関数がオーバーライドされ、Cat の関数が print() 内で実行されます .

  • C言語

    1. C++ プログラミングで配列を関数に渡す
    2. C++ クラスとオブジェクト
    3. C++ フレンド関数とフレンド クラス
    4. C++ クラス テンプレート
    5. C++ 関数とプログラム例
    6. Verilog 関数
    7. C - 関数
    8. C++ のストレージ クラス
    9. C++ オーバーロード (演算子と関数)
    10. C++ のポリモーフィズム
    11. C++ でのデータの抽象化