ホームページ >バックエンド開発 >C++ >オブジェクト指向プログラミングにおける仮想関数と純粋仮想関数の違いは何ですか?

オブジェクト指向プログラミングにおける仮想関数と純粋仮想関数の違いは何ですか?

DDD
DDDオリジナル
2024-12-26 02:21:10753ブラウズ

What's the Difference Between Virtual and Pure Virtual Functions in Object-Oriented Programming?

仮想関数と純粋仮想関数を理解する

仮想関数は、実行時ポリモーフィズムを有効にすることにより、オブジェクト指向プログラミングにおいて重要な役割を果たします。 Wikipedia で定義されているように、仮想関数は動的ディスパッチを可能にするオーバーライド可能なメソッドまたは関数です。これは、実行される特定の関数がコンパイル時ではなく実行時のオブジェクトの型に基づいて決定されることを意味します。

非仮想関数とは対照的に、仮想関数が派生クラスでオーバーライドされる場合は、 、最も派生したクラスで定義されたバージョンがクラス階層全体で使用されます。これにより、関数の最も具体的な実装が常に利用されることが保証されます。

純粋仮想関数 (純粋仮想メソッドとも呼ばれます) は、この概念をさらに発展させたものです。これらは仮想関数であり、派生クラスが抽象クラスでない場合は、そのクラスに実装する必要があります。そのため、純粋仮想関数は、派生クラスに特定の動作が存在することを事実上強制します。

抽象クラスは、1 つ以上の純粋仮想関数を含むクラスです。このようなクラスは直接インスタンス化できません。代わりに、すべての純粋仮想関数の実装を提供する派生クラスを使用する必要があります。

仮想関数と純粋仮想関数の違いを説明するには、次の C を考慮してください。コード:

Base.hpp:

struct Base {
    virtual ~Base() = default;
    virtual void foo() {
        std::cout << "Base::Foo" << std::endl;
    }
};

派生d.hpp:

struct Derived : public Base {
    void foo() override {
        std::cout << "Derived::Foo" << std::endl;
    }
};

main.cpp:

int main() {
    Base base;
    base.foo();  // Calls Base::Foo

    Derived derived;
    derived.foo();  // Calls Derived::Foo

    Base* derived_as_base = &derived;
    derived_as_base->foo();  // Calls Derived::Foo (due to dynamic dispatch)
}

このコードでは、Base クラスには「Base::Foo」を出力する仮想関数 foo が含まれています。 Derived クラスはこの関数をオーバーライドして、「Derived::Foo」を出力します。 Base オブジェクトが foo を呼び出すと、出力は「Base::Foo」になります。ただし、Derived オブジェクト (Base ポインターとしてアクセスされる) が foo を呼び出すと、動的ディスパッチにより出力は "Derived::Foo" になります。

ここで、純粋な仮想オブジェクトを考えてみましょう。 function:

PureBase.hpp:

struct PureBase {
    virtual ~PureBase() = default;
    virtual void foo() = 0;  // Pure virtual function
};

PureDerived.hpp:

struct PureDerived : public PureBase {
    void foo() override {
        std::cout << "PureDerived::Foo" << std::endl;
    }
};

このコードでは、 PureBase クラスには、基本クラスで定義されていない純粋仮想関数 foo が含まれています。その結果、PureBase クラスは完全な実装が欠けているため抽象クラスになります。

PureMain.cpp:

int main() {
    // error: cannot declare variable 'pureBase' to be of abstract type 'PureBase'
    // PureBase pureBase;
    // pureBase.foo();

    PureDerived pureDerived;
    pureDerived.foo();  // Calls PureDerived::Foo
}

この例では、PureBase をインスタンス化しようとしています。オブジェクトを使用すると、直接コンパイラ エラーが発生します。ただし、PureDerived オブジェクトの作成は、foo 関数の実装を提供するため許可されます。

要約すると、仮想関数は動的ディスパッチを提供し、派生クラスでオーバーライドできます。一方、純粋仮想関数は派生クラスに実装し、特定の動作を強制する必要があります。これらの概念は共に、オブジェクト指向プログラミングでポリモーフィック機能を実現する上で重要な役割を果たします。

以上がオブジェクト指向プログラミングにおける仮想関数と純粋仮想関数の違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。