C++ でオブジェクト型を検索

Faiq Bilal 2023年10月12日
  1. C++ でクラス オブジェクトの型を見つける
  2. typeid().name() を使用して C++ でクラス オブジェクトの型を検索する
  3. typeid.().name()__cxa_demangle とともに使用して、C++ でクラス オブジェクトの型を検索する
C++ でオブジェクト型を検索

この記事では、C++ でオブジェクトの型を見つけるさまざまな方法について説明します。

C++ でクラス オブジェクトの型を見つける

単純な変数に int や bool などのデータ型があるのと同様に、クラス オブジェクトには、それらが属するクラスの型があります。

#include <iostream>

using namespace std;

class Vehicles {
 public:
  string make;
  string model;
  string year;
};

int main() { Vehicles car; }

上記の例では、carVehicles のオブジェクトであるため、main() で定義されたオブジェクト car のタイプはクラス Vehicles です。

上記の例は非常に単純で、オブジェクトの種類を簡単に識別できました。 しかし、より複雑なプロジェクトでは、特に複数のクラスとオブジェクトがあり、複数のプログラマーが共同で作業している場合、オブジェクトの種類を追跡すると、非常に混乱する可能性があります。

この問題を回避するために、いくつかの方法を使用してオブジェクトのタイプを判別できます。以下の例でそれらについて説明します。

typeid().name() を使用して C++ でクラス オブジェクトの型を検索する

typeid() は typeinfo ライブラリに含まれるメソッドです。 typeid.().name() 関数は、変数またはクラス オブジェクトを受け取り、その型の名前を文字列として返します。

typeid.().name() 関数の使用法を以下に示します。

#include <iostream>
#include <typeinfo>

using namespace std;

class Vehicles {
 public:
  string make;
  string model;
  string year;
};

class Aircraft {
 public:
  string make;
  string model;
  string year;
};

int main() {
  int x;
  float y;
  bool b;

  Vehicles car;
  Aircraft helicopter;

  cout << "The type of the variable x "
       << " is " << typeid(x).name() << endl;
  cout << "The type of the variable y "
       << " is " << typeid(y).name() << endl;
  cout << "The type of the variable b "
       << " is " << typeid(b).name() << endl;
  cout << "The type of the object car "
       << " is " << typeid(car).name() << endl;
  cout << "The type of the object helicopter "
       << " is " << typeid(helicopter).name() << endl;
}

上記のコード スニペットは、次の出力を生成します。

The type of the variable x  is i
The type of the variable y  is f
The type of the variable b  is b
The type of the object car  is 8Vehicles
The type of the object helicopter  is 8Aircraft

上記のように、typeid.().name() 関数は、単純な変数とユーザー定義のクラス オブジェクトの両方で機能します。 この関数は、int、float、および bool に対してそれぞれ if、および b を返します。

この関数は、オブジェクト carhelicopter のそれぞれのクラスの名前を返します。 この例では、出力クラス名の前に数字 8 が付いていることに注意してください。これは、クラス名と変数名が C++ のコンテキストでどのように格納されるかによるためです。

typeid.().name() 関数は、クラス オブジェクティブで使用する場合、システムおよびコンパイラに依存し、クラス名を返すときに任意の文字をクラス名の前に追加できます。 使用されているシステムでは、コンパイラはクラス名の前にクラス名の文字数を追加します。つまり、VehicleAircraft の両方の名前に 8 文字が含まれます。

typeid.().name() は実装に依存するため、c++filt コマンドまたは __cxa_demangle を使用してデマングルされたクラス名を返します。

クラス名はマングル形式で返されますが、読み取り可能であり、オブジェクトのクラスを識別するために使用できます。 また、戻り値の型が文字列であるため、オブジェクトを簡単に比較して、同じクラスであるかどうかを確認できます。

typeid.().name()__cxa_demangle とともに使用して、C++ でクラス オブジェクトの型を検索する

前の例で示したように、typeid.().name() を使用すると、マングルされたクラス名と変数の型が返されます。 デマングルされた結果を取得するには、cxxabi.h ライブラリから __cxa_demangle 関数を使用できます。

__cxa_demangle の構文は次のとおりです。

char *abi::__cxa_demangle(const char *mangled_name, char *output_buffer, size_t *length, int *status)

typeid.().name()__cxa_demangle を使用する例を以下に示します。

#include <cxxabi.h>

#include <iostream>

using namespace std;

class Vehicles {
 public:
  string make;
  string model;
  string year;
};

class Aircraft {
 public:
  string make;
  string model;
  string year;
};

int main() {
  int x;
  float y;
  bool b;

  Vehicles car;
  Aircraft helicopter;

  cout << "The type of the variable x "
       << " is "
       << abi::__cxa_demangle(typeid(x).name(), nullptr, nullptr, nullptr)
       << endl;
  cout << "The type of the variable y "
       << " is "
       << abi::__cxa_demangle(typeid(y).name(), nullptr, nullptr, nullptr)
       << endl;
  cout << "The type of the variable b "
       << " is "
       << abi::__cxa_demangle(typeid(b).name(), nullptr, nullptr, nullptr)
       << endl;
  cout << "The type of the object car "
       << " is "
       << abi::__cxa_demangle(typeid(car).name(), nullptr, nullptr, nullptr)
       << endl;
  cout << "The type of the object helicopter "
       << " is "
       << abi::__cxa_demangle(typeid(helicopter).name(), nullptr, nullptr,
                              nullptr)
       << endl;
}

この例の範囲では、__cxa_demangle 関数の最初の引数、つまりマングルされた名前だけに関心がありました。 この場合、残りの引数は必要ありませんでした。

上記のコードは、次の出力を生成します。

The type of the variable x  is int
The type of the variable y  is float
The type of the variable b  is bool
The type of the object car  is Vehicles
The type of the object helicopter  is Aircraft

出力からわかるように、返された変数名と型名はデマングルされ、コード ファイルでの動作とまったく同じように表示されます。