仮想関数とvtable
仮想関数で実行時ポリモーフィズムを実装し、vtableの概念を確認します。
「仮想関数とvtable」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。
静的バインディングと動的バインディング
デフォルトでは、メンバー呼び出しは静的にバインドされます。コンパイラーは、宣言された型に基づいて関数を選択します。virtual 関数を使用すると、呼び出しは実際の型に基づいて動的にバインドされます。
virtual 関数の宣言
基底クラスで関数に virtual を付けます。派生クラスはその関数をオーバーライドできます。
class Shape {
public:
virtual double area() const = 0; // pure virtual
virtual ~Shape() = default;
};
class Circle : public Shape {
double r_;
public:
Circle(double r) : r_(r) {}
double area() const override { return 3.14159 * r_ * r_; }
};override 指定子
派生クラスのメソッドに override を追加します。コンパイラーが、その関数が実際に仮想関数をオーバーライドしているか検証するため、シグネチャのタイプミスを検出できます。
final 指定子
final は、それ以降のオーバーライドを禁止します。継承させたくないクラスや、これ以上オーバーライドさせたくないメソッドに使用します。
class Concrete final : public Base { /* ... */ };
class Base {
virtual void f() final; // cannot be overridden
};基底クラスのポインター経由での呼び出し
これがポリモーフィズムの力です。基底クラスのポインターから、正しい派生クラスのメソッドを呼び出せます。
Shape* s = new Circle(3.0);
std::cout << s->area(); // 28.27... (Circle::area)
delete s;vtable の概念
ポリモーフィックな各クラスには、関数ポインターのテーブルである隠しvtableがあります。各オブジェクトは、そのクラスの vtable を指す隠しポインター(vptr)を保持します。
仮想関数呼び出しのコスト
仮想関数の呼び出しでは、vtable を介した追加の間接参照が 1 回発生します。ほとんどのコードでは無視できるコストです。測定によってボトルネックだと判明した場合は、内部ループでの使用を避けてください。
純粋仮想関数
= 0 を付けると、関数を純粋仮想にできます。派生クラスは、そのクラスをインスタンス化できるようにするため、関数をオーバーライドする必要があります。クラスは抽象クラスになります。
仮想デストラクター
クラスに仮想関数が 1 つでもある場合、または基底クラスのポインター経由で削除する予定がある場合は、仮想デストラクターを用意してください。そうしないと、派生クラスのデストラクターは実行されません。
class Base {
public:
virtual ~Base() = default; // safe to delete through Base*
};スマートポインターによるポリモーフィズム
ポリモーフィックなオブジェクトは、基底クラスへのスマートポインターで保持します。スマートポインターが正しく破棄を処理します。
std::unique_ptr<Shape> s = std::make_unique<Circle>(3.0);スライシングの再確認
派生オブジェクトを、基底クラスを受け取る関数に値渡しすると、派生部分が切り捨てられます。ポリモーフィックな引数には、参照またはポインターを使用してください。
パフォーマンスのトレードオフ
仮想関数は、わずかなランタイムコストで柔軟性をもたらします。テンプレートはランタイムコストなしでコンパイル時ポリモーフィズムを実現します。ポリモーフィズムがランタイムに必要かどうかに基づいて選択してください。
理解度チェック
ポリモーフィックな基底クラスに virtual デストラクターを持たせるべきなのはなぜですか。
まとめ
仮想関数は、クラスごとに用意される vtable を通じてランタイムポリモーフィズムを実現します。オーバーライドには override を付け、final でそれ以降の継承を禁止します。ポリモーフィックな基底クラスには、必ず仮想デストラクターを用意してください。
よくある質問
「仮想関数とvtable」レッスンは無料ですか?
はい。「仮想関数とvtable」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。
「仮想関数とvtable」で何を学びますか?
仮想関数で実行時ポリモーフィズムを実装し、vtableの概念を確認します。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C++ Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「仮想関数とvtable」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC++ Academyレッスンでコードを書いて実行できますか?
はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 単一継承と多重継承
- 仮想関数とvtable
- 抽象クラスと純粋仮想メソッド
- 継承とコンポジションのトレードオフ