C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++の純粋仮想関数と抽象クラスを徹底解説!基本概念から実装例まで

はじめに

C++には、オブジェクト指向設計において重要な役割を果たす純粋仮想関数抽象クラスという仕組みがあります。これらを理解することで、柔軟で拡張性の高いクラス設計が可能になります。

本記事では、純粋仮想関数と抽象クラスの基本概念、特徴、そして実際のコード例を通じて、わかりやすく解説していきます。

純粋仮想関数とは?

純粋仮想関数とは、C++における仮想関数の一種で、関数の定義(処理内容)を持たず、宣言のみを行う特殊な関数です。宣言の末尾に = 0 を代入することで宣言されます。

virtual void s() = 0; // 純粋仮想関数の宣言

抽象クラスとは?

抽象クラスとは、少なくとも1つの純粋仮想関数を持つクラスのことです。抽象クラスは「設計図」としての役割を担い、具体的な実装は派生クラスに委ねられます。

抽象クラスの特徴

  • 抽象クラスには、純粋仮想関数だけでなく、通常のメンバ関数やメンバ変数も含めることができます。

  • 抽象クラスはインスタンス化(オブジェクト生成)できない一方で、抽象クラス型のポインタや参照は作成できます。

  • 抽象クラスは主にアップキャストのために使われ、派生クラスが共通のインターフェースを利用できるようにします。

  • 抽象クラスから派生クラスを作成する場合、すべての純粋仮想関数を実装する必要があります。未実装の場合、その派生クラスも抽象クラスになります。

  • 純粋仮想関数があると、Vtable(仮想関数テーブル)にスロットが確保されるものの、そこに関数のアドレスが設定されないためVtableが不完全な状態になります。このため、抽象クラスのオブジェクトは作成できません。

サンプルコード

以下は、抽象クラスと純粋仮想関数を使用した基本的なコード例です。

#include<iostream>
using namespace std;

class B {
public:
    virtual void s() = 0; // 純粋仮想関数
};

class D : public B {
public:
    void s() { // 純粋仮想関数の実装
        cout << "Virtual Function in Derived class\n";
    }
};

int main() {
    B *b;       // 抽象クラス型のポインタは作成可能
    D dobj;     // 具象クラスのオブジェクトを生成
    b = &dobj;  // アップキャスト
    b->s();     // 派生クラスの関数が呼ばれる
}

実行結果

Virtual Function in Derived class

コードのポイント

この例では、抽象クラス B のポインタ b を通じて、派生クラス D のオブジェクトを操作しています。b->s() を呼び出すと、多態性(ポリモーフィズム)により、派生クラス側で実装された関数が実行されます。

まとめ

純粋仮想関数と抽象クラスは、C++におけるインターフェース設計の基礎となる重要な概念です。抽象クラスを使いこなすことで、共通のインターフェースを定義しつつ、実装の詳細を派生クラスに任せる、保守性の高いコードを書くことができます。ぜひ実際のコードで試してみてください。

  1. C#の抽象クラス(abstract class)とは?基本から実例までわかりやすく解説

    抽象クラスとは C#における抽象クラス(abstract class)は、abstractキーワードを使って宣言される特殊なクラスです。抽象クラスには、実装を持たない「抽象メソッド」と、通常の処理を持つ「非抽象メソッド」の両方を含めることができます。 最大の特徴は、抽象クラスは直接インスタンス化できないという点です。newキーワードでオブジェクトを生成することはできず、必ず派生クラスを通じて利用します。この仕組みにより、「共通の設計図を基底クラスで定義し、具体的な実装は各派生クラスに任せる」というポリモーフィズム(多態性)を実現できます。 抽象クラスの基本的な宣言方法 以下は、抽象クラスVe

  2. Scalaのトレイト(Trait)と抽象クラスの違いを徹底解説

    Scalaには、共通の振る舞いを定義するための仕組みとして「トレイト(Trait)」と「抽象クラス(Abstract Class)」の2つがあります。どちらも抽象メンバーを持てる点は似ていますが、継承モデルや構文上の制約など、重要な違いがいくつか存在します。本記事では、それぞれの特徴とサンプルコード、そして両者の違いを比較表でわかりやすく解説します。 トレイト(Trait)とは トレイトは、Javaのインターフェースに似た概念で、traitキーワードを使って定義します。抽象メソッドだけでなく、実装を持つ具象メソッドも含めることができ、複数のトレイトを1つのクラスにミックスインできる点が大きな特