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

C++でインターフェイスを宣言する方法|抽象クラスと純粋仮想関数の基礎

インターフェイスとは、C++クラスの振る舞いや能力を、そのクラスの具体的な実装に縛られずに記述するための仕組みです。C++では、インターフェイスは抽象クラスを使って実装されます。ただし、抽象クラスは「実装の詳細をデータから分離する」という概念であるデータ抽象化とは別物なので、両者を混同しないように注意しましょう。

純粋仮想関数でクラスを抽象化する

クラスを抽象クラスにするには、少なくとも1つのメンバ関数を純粋仮想関数として宣言します。純粋仮想関数は、宣言の末尾に「= 0」を付けることで指定できます。

class Box {
public:
    // 純粋仮想関数
    virtual double getVolume() = 0;

private:
    double length;   // 直方体の長さ
    double breadth;  // 直方体の幅
    double height;   // 直方体の高さ
};

抽象クラス(ABC)の役割

抽象クラス(Abstract Base Class:ABCとも呼ばれます)の目的は、他のクラスが継承できる適切な基底クラスを提供することです。抽象クラスはオブジェクトの生成(インスタンス化)には使えず、あくまでインターフェイスとしてのみ機能します。抽象クラスのオブジェクトをインスタンス化しようとすると、コンパイルエラーが発生します。

したがって、ABCのサブクラスをインスタンス化したい場合は、基底クラスで宣言されたすべての純粋仮想関数を実装(オーバーライド)しなければなりません。これは、そのクラスがABCの宣言するインターフェイスをサポートしていることを意味します。逆に、派生クラスで純粋仮想関数をオーバーライドせずにそのクラスのオブジェクトを生成しようとすると、コンパイルエラーとなります。

一方、オブジェクトの生成に利用できるクラスは具象クラスと呼ばれます。

実装例:Shapeクラスによるインターフェイス

次の例では、親クラスであるShapegetArea()という関数のためのインターフェイスを提供し、それを各派生クラスが独自の方法で実装しています。

サンプルコード

#include <iostream>
using namespace std;

class Shape { // 基底クラス
public:
    // インターフェイスの枠組みとなる純粋仮想関数
    virtual int getArea() = 0;

    void setWidth(int w) {
        width = w;
    }

    void setHeight(int h) {
        height = h;
    }

protected:
    int width;
    int height;
};

class Rectangle : public Shape { // 派生クラス
public:
    int getArea() {
        return (width * height);
    }
};

class Triangle : public Shape {
public:
    int getArea() {
        return (width * height) / 2;
    }
};

int main(void) {
    Rectangle Rect;
    Triangle Tri;

    Rect.setWidth(5);
    Rect.setHeight(7);

    // 長方形の面積を出力
    cout << "Total Rectangle area: " << Rect.getArea() << endl;

    Tri.setWidth(5);
    Tri.setHeight(7);

    // 三角形の面積を出力
    cout << "Total Triangle area: " << Tri.getArea() << endl;

    return 0;
}

実行結果

Total Rectangle area: 35
Total Triangle area: 17

この例からわかるように、抽象クラスShapegetArea()という形でインターフェイスを定義し、RectangleTriangleの2つのクラスが同じ関数名を持ちながらも、それぞれの図形に合わせた異なるアルゴリズムで面積を計算しています。

デザイン戦略(設計戦略)

オブジェクト指向システムでは、抽象基底クラスを使って、外部アプリケーション全体に共通する標準化されたインターフェイスを提供することがよくあります。その抽象基底クラスからの継承を通じて、同じように動作する派生クラス群が構築されていきます。

外部アプリケーションに対して提供される機能(公開関数)は、抽象基底クラス内で純粋仮想関数として定義されます。そして、これらの純粋仮想関数の実際の実装は、アプリケーションの具体的な種類に応じた派生クラスによって提供されます。

このようなアーキテクチャを採用することで、システムが一度定義された後でも、新しいアプリケーションを容易に追加できる柔軟性が得られます。

  1. C++のnew演算子を使って2次元配列を動的に宣言・生成する方法

    動的な2次元配列とは、基本的に「配列へのポインタ」を要素とする配列(ポインタの配列)のことです。つまり、各行が独立した1次元配列としてヒープ上に確保され、それらの先頭アドレスを格納するポインタ配列によって全体が管理されます。下図は、3×4の2次元配列のイメージです。アルゴリズムC++のnew演算子で2次元配列を動的に確保する手順は以下の通りです。Begin 配列の寸法(行数・列数)を宣言する。 new を使って 2次元配列 a[][] を動的に確保する。 配列に要素を代入する。 配列の内容を出力する。 delete でメモリを解放する。 Endサンプルコ

  2. Pythonでグローバル変数を宣言する方法!globalキーワードの基本と実例を解説

    グローバル変数とは何か?グローバル変数(大域変数)とは、プログラム全体で有効なスコープを持つ変数のことです。別の場所で同じ名前の変数によって上書き(シャドウイング)されない限り、プログラム内のどこからでも参照・アクセスできます。すべてのグローバル変数の集合は、プログラムの「グローバル環境」または「グローバルスコープ」と呼ばれます。Pythonでは、変数名の前に global キーワードを付けることで、その変数をグローバル変数として宣言できます。なお、すべての変数には「宣言・定義されたブロック」がスコープとして適用されます。つまり、変数は宣言された位置より後のコードでのみ使用可能である点に注意し