ホームページ  >  記事  >  バックエンド開発  >  仮想メソッドおよび仮想テーブルにおける C++ 関数ポインターの用途は何ですか?

仮想メソッドおよび仮想テーブルにおける C++ 関数ポインターの用途は何ですか?

王林
王林オリジナル
2024-04-17 18:00:021037ブラウズ

C 関数ポインタは、派生クラスのオーバーライドされたメソッド実装へのポインタを格納するために仮想メソッドで使用され、仮想テーブルを初期化して仮想メソッド実装へのポインタを格納するために仮想テーブルで使用され、それによってランタイムが実現されます。このクラスは、基本クラスの仮想メソッドをオーバーライドし、実行時にオブジェクトの実際の型に基づいて正しい実装を呼び出します。

C++ 函数指针在虚拟方法和虚表中的应用有哪些?

C 関数ポインタ: 仮想メソッドと仮想テーブルのアプリケーション

C では、関数ポインタは仮想メソッドと仮想テーブルの実装に使用されます。仮想テーブルの維持は重要な役割を果たします。この記事では、これらのアプリケーションについて掘り下げ、実際の事例を通じて理解を深めます。

仮想メソッド

仮想メソッドは、基本クラスで宣言され、派生クラスによってオーバーライドされるメンバー関数です。仮想メソッドが基本クラス ポインターを通じて呼び出される場合、派生クラスの実装はランタイム オブジェクトの実際の型に基づいて呼び出されます。

仮想メソッドを実装するために、コンパイラは基本クラスごとに仮想関数テーブル (vtable) を作成します。このテーブルには、各仮想メソッドの実装へのポインタが格納されます。仮想メソッドが呼び出されるとき、コンパイラはオブジェクトの vtable を使用して正しい実装を見つけて呼び出します。

仮想メソッドでの関数ポインタの適用

関数ポインタは、vtable 内の仮想メソッド実装へのポインタを格納するために使用されます。コンパイラは、仮想メソッドごとに vtable エントリを割り当て、そのエントリにメソッドの実装を指す関数ポインタを設定します。

例:

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

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

int main() {
    Base* base = new Derived;
    base->print(); // 输出 "Derived::print"
}

この例では、コンパイラは 2 つのエントリを含む vtable を作成します。最初のエントリは、基本クラス Baseprint() メソッドの実装を指し、2 番目のエントリは、派生クラス のオーバーライドされた print を指します。派生 () メソッドの実装。 base->print() が実行されると、コンパイラは vtable を使用して適切な関数ポインタを取得し、対応する実装を呼び出します。

仮想テーブル

仮想テーブルは、仮想メソッド実装を指す関数ポインターを格納するために使用されるデータ構造です。仮想テーブルの各エントリは、基本クラスで宣言された仮想メソッドに対応します。

仮想テーブルでの関数ポインタの適用

関数ポインタは、仮想テーブルを初期化し、仮想メソッド実装へのポインタを格納するために使用されます。コンパイラは、クラスに仮想メソッドが含まれていることを検出すると、そのクラスの vtable を生成します。仮想テーブル内の各エントリの型は、メソッドの戻り値の型に対応する関数ポインタです。

前の例では、コンパイラは基本クラス Base の 2 つのエントリを含む仮想テーブルを生成します。

vtable[Base] = {
    Base::print,
    Derived::print
};

実用的なケース

実際の例を通じて、仮想メソッドと仮想テーブルにおける関数ポインターの適用についてさらに理解してみましょう。単純な図形描画ライブラリを作成しましょう:

class Shape {
public:
    virtual void draw() = 0;
};

class Circle : public Shape {
public:
    virtual void draw() override {
        cout << "Drawing a circle..." << endl;
    }
};

class Square : public Shape {
public:
    virtual void draw() override {
        cout << "Drawing a square..." << endl;
    }
};

int main() {
    vector<Shape*> shapes;
    shapes.push_back(new Circle);
    shapes.push_back(new Square);

    for (auto shape : shapes) {
        shape->draw();
    }
}

この例では、Shape クラスが基本クラスであり、CircleSquare派生クラスです。 draw() メソッドは仮想メソッドであり、各派生クラスによってオーバーライドされます。コンパイラは、各派生クラスの draw() メソッド実装への関数ポインタを含む Shape クラスの vtable を作成します。

shape->draw() が呼び出されると、コンパイラはオブジェクトの vtable を使用して適切な関数ポインタを取得し、正しい実装を呼び出します。これにより、明示的な変換を必要とせずに、統合された Shape インターフェイスを通じてさまざまなタイプの形状を描画できるようになります。

以上が仮想メソッドおよび仮想テーブルにおける C++ 関数ポインターの用途は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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