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

C++のstd::is_abstractテンプレートの使い方を解説!抽象クラスの判定方法

本記事では、C++ STLに含まれるstd::is_abstractテンプレートの動作、構文、そして具体的な使用例について詳しく解説します。

is_abstractテンプレートを使用すると、指定したクラスが抽象クラス(abstract class)であるかどうかを簡単にチェックできます。

抽象クラスとは?

抽象クラスとは、少なくとも1つの純粋仮想関数(Pure Virtual Function)を持つクラスのことです。

抽象クラスが使われるのは、関数の宣言時点では実装内容が確定していないようなケースです。「システム上にこの種の機能が必要なことは分かっているが、具体的な処理の内容はまだ決められない」という状況で役立ちます。この場合、宣言だけを行い実装を持たない純粋仮想関数を定義します。

そして、あるクラスのインスタンスからそのクラスが抽象クラスかどうかを判定したいときに、is_abstract()を使用します。

is_abstract()はintegral_constantから継承されており、型Tが多相的(polymorphic)なクラス型であるかどうかに応じて、true_typeまたはfalse_typeを返します。

構文

template <class T> struct is_abstract;

パラメータ

このテンプレートが受け取れるパラメータはTのみです。Tは判定対象となるクラス型で、そのクラスが抽象クラスかどうかを調べます。

戻り値

この関数はbool型の値(trueまたはfalse)を返します。

  • Tが抽象クラスの場合 → true
  • Tが抽象クラスでない場合 → false

使用例1

#include <iostream>
#include <type_traits>
using namespace std;
struct TP_1 {
    int var;
};
struct TP_2 {
    virtual void dummy() = 0;
};
class TP_3 : TP_2 {
};
int main() {
    cout << boolalpha;
    cout << "checking for is_abstract: ";
    cout << "\nstructure TP_1 with one variable :"<< is_abstract<TP_1>::value;
    cout << "\nstructure TP_2 with one pure virtual function : "<< is_abstract<TP_2>::value;
    cout << "\nclass TP_3 which is derived from TP_2 structure : "<< is_abstract<TP_3>::value;
    return 0;
}

出力結果

上記のコードを実行すると、以下の出力が生成されます。

checking for is_abstract:
structure TP_1 with one variable : false
structure TP_2 with one pure virtual function : true
class TP_3 which is derived from TP_2 structure : true

解説:TP_1は通常のメンバ変数のみを持つためfalse。TP_2は純粋仮想関数を持つためtrue。TP_3はTP_2を継承しており純粋仮想関数を実装していないため、これも抽象クラスとなりtrueが返されます。

使用例2

#include <iostream>
#include <type_traits>
using namespace std;
struct TP_1 {
    virtual void dummy() = 0;
};
class TP_2 {
    virtual void dummy() = 0;
};
struct TP_3 : TP_2 {
};
int main() {
    cout << boolalpha;
    cout << "checking for is_abstract: ";
    cout << "\nstructure TP_1 with one pure virtual function :"<< is_abstract<TP_1>::value;
    cout << "\nclass TP_2 with one pure virtual function : "<< is_abstract<TP_2>::value;
    cout << "\nstructure TP_3 which is derived from TP_2 class : "<< is_abstract<TP_3>::value;
    return 0;
}

出力結果

上記のコードを実行すると、以下の出力が生成されます。

checking for is_abstract:
structure TP_1 with one pure virtual function : true
class TP_2 with one pure virtual function : true
structure TP_3 which is derived from TP_2 class : true

解説:structでもclassでも、純粋仮想関数を持っていれば抽象クラスとして判定されます。また、抽象クラスを継承しただけで純粋仮想関数をオーバーライドしていないTP_3も、やはり抽象クラスとみなされます。

まとめ

std::is_abstractは、<type_traits>ヘッダで提供される型特性(type traits)の一つであり、コンパイル時に型Tが抽象クラスかどうかを判定できます。テンプレートメタプログラミングやSFINAEなどの場面で、型の性質に応じた処理の分岐に活用できる便利なツールです。

  1. C++における構造体とクラスの違いとは?アクセス指定子の挙動を実例付きで解説

    はじめにC++において、構造体(struct)とクラス(class)は本質的にはほぼ同じものです。どちらもメンバ変数やメンバ関数を持つことができ、継承・カプセル化といったオブジェクト指向の機能も同様に利用できます。しかし、両者にはいくつかの細かな違いが存在します。この記事では、その違いをサンプルコードと実行結果を交えてわかりやすく解説します。違い1:メンバのデフォルトのアクセスレベル最も大きな違いは、メンバのデフォルトのアクセス権限です。クラスのメンバはデフォルトで「private(非公開)」になりますが、構造体のメンバはデフォルトで「public(公開)」になります。実際に、以下の2つのコー

  2. C++のローカルクラスとは?特徴・制約と実装例をわかりやすく解説

    ローカルクラスとは C++において、関数の中で宣言されたクラスは「ローカルクラス」と呼ばれます。これは、そのクラスが定義された関数の内部でのみ有効であるためです。 まず、ローカルクラスの基本的な構造を見てみましょう。 #include<iostream> using namespace std; void func() { class LocalClass { }; } int main() { return 0; } 上記の例では、関数 func() の中で LocalClass が定義されています。このように関数の内部で宣言されたクラスが、ローカルクラス