最終更新:2026-10-12
C 言語による C++ 多態の実現¶
著者について:¶
個人公式アカウント:

1.C++での実装例¶
C++における多態:C++では仮想関数テーブルが管理されており、代入互換ルールにより、基底クラスのポインタや参照は派生クラスのオブジェクトを指せることがわかっています。
基底クラスのポインタまたは参照が基底クラスの仮想関数を呼び出す場合、その基底クラスのポインタは自分の仮想関数テーブルの中から自分の関数アドレスを探します。もし基底クラスオブジェクトのポインタまたは参照が派生クラスのオブジェクトを指していて、その派生クラスが基底クラスの仮想関数をオーバーライド済みであれば、そのポインタは派生クラスでオーバーライドされた仮想関数を呼び出します。
学習用のコードはこちら:c++_examp.cpp
2.Cによる実現¶
- カプセル化
C言語にはclassという概念はありませんが、struct構造体があるので、structを使って模倣することが考えられます。
関数ポインタを使って、属性とメソッドを構造体にカプセル化します。
- 継承
構造体のネスト
- 多態
クラスとサブクラスのメソッドの関数ポインタが異なる
C言語の構造体の内部にはメンバ関数がありません。では、この親構造体と子構造体に共通の関数はどう実現すればよいのでしょうか?関数ポインタを使って模倣することが考えられます。しかしこの方法には欠点があります。親子それぞれの関数ポインタが指す先は、C++で管理される仮想関数テーブルのようなものではなく、ひとつの物理メモリであり、模倣する関数が多くなると管理が難しくなります。
多態を模倣するには、関数ポインタ変数の配置を一致させる必要があります(内容が完全に一致し、かつ変数のアライメントも完全に一致していること)。そうしないと、親クラスのポインタが子クラスのオブジェクトを指したとき、実行時にクラッシュします!
学習用のコードはこちら:c_examp.c
関連トピック¶
- C++ 純粋仮想関数と抽象クラス | C++那些事
- C++ assert アサーション | C++那些事
- C++ ビットフィールド | C++那些事
- C++ const 定数と修飾 | C++那些事
- C++ const ファミリー | C++那些事
- C++ 間接参照演算子 * | C++那些事
- C++ 初期化と代入 | C++那些事
- C++ 複数戻り値の書き方 | C++那些事
- C++ mutable キーワード | C++那些事
- C++ restrict とコンパイル最適化 | C++那些事