Verwendung von den typeid-Operator in C++

Jinku Hu 12 Oktober 2023
Verwendung von den typeid-Operator in C++

Dieser Artikel erklärt und demonstriert die Verwendung des Operators typeid in C++.

Verwenden Sie den Operator typeid, um den Typnamen des Objekts in C++ abzurufen

Sie können den Operator typeid verwenden, um die Typinformationen des angegebenen Ausdrucks oder Objekts abzurufen. Es gibt eine Referenz auf den Standard-Bibliothekstyp std::type_info zurück, der in einem <typeinfo>-Header definiert ist.

Das Objekt std::type_info hat die Memberfunktion name, mit der Sie eine Zeichenkette zurückgeben können, die den zugrunde liegenden Typ des Argumentobjekts beschreibt. Beachten Sie, dass die von typeid abgerufenen Typinformationen implementierungsabhängig sind. Die gängigsten Compiler gcc und clang geben nämlich verstümmelte Namen zurück, wie im nächsten Codebeispiel gezeigt.

Andere Implementierungen wie Microsoft Visual C++ zeigen Informationen in besser lesbarer Form an. Denken Sie jedoch daran, dass Sie immer noch lernen können, die Namen für die integrierten Typen zu identifizieren, die von der vorherigen Implementierung angezeigt werden. Zum Beispiel gibt das int-Objekt ein i-Zeichen zurück, und ein Zeiger auf das int-Objekt gibt eine Pi-Zeichenkette zurück.

#include <iostream>
#include <string>
#include <typeinfo>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main() {
  int i1 = 1234;
  string str1("arbitrary string");
  auto ptr = &i1;

  cout << "i1 type: " << typeid(i1).name() << '\n'
       << "str1 type: " << typeid(str1).name() << '\n'
       << "ptr type: " << typeid(ptr).name() << endl;

  const std::type_info& r1 = typeid(i1);
  cout << '\n' << "i1 type: " << r1.name() << '\n';

  return EXIT_SUCCESS;
}

Ausgabe:

i1 type: i
str1 type: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
ptr type: Pi

i1 type: i

Auf der anderen Seite, wenn wir den Befehl typeid für Referenzen auf Objekte aufrufen, werden wir feststellen, dass die abgerufenen Typinformationen nicht immer genau und manchmal zu kryptisch sind, um lesbar zu sein. Das folgende Beispiel zeigt einen solchen Fall, in dem der zweite Aufruf des Operators typeid die Typinformationen falsch zurückgibt.

#include <iostream>
#include <string>
#include <typeinfo>

using std::cout;
using std::endl;

struct Base {};
struct Derived : Base {};

struct Base2 {
  virtual void foo() {}
};
struct Derived2 : Base2 {};

int main() {
  Derived d1;
  Base& b1 = d1;
  cout << "non-polymorphic base: " << typeid(b1).name() << '\n';

  Derived2 d2;
  Base2& b2 = d2;
  cout << "polymorphic base: " << typeid(b2).name() << '\n';

  return EXIT_SUCCESS;
}

Ausgabe:

non-polymorphic base: 4Base
polymorphic base: 8Derived2

Dieses Verhalten kann mit der Boost TypeIndex-Bibliotheksfunktion type_id_with_cvr korrigiert werden, die die Typinformationen genau zurückgeben kann. Im Allgemeinen verursachen Objekte mit den Modifikatoren const, volatile, & und && alle falsche Typinformationen, wenn der Operator typeid verwendet wird; Daher sollten Sie sich besser auf die Funktion type_id_with_cvr verlassen.

Für das folgende Codebeispiel muss die Boost-Bibliothek auf dem System installiert sein und die Funktion type_id_with_cvr befindet sich im Namensraum boost::typeindex.

#include <boost/type_index.hpp>
#include <iostream>
#include <string>
#include <typeinfo>

using boost::typeindex::type_id_with_cvr;
using std::cout;
using std::endl;

struct Base {};
struct Derived : Base {};

struct Base2 {
  virtual void foo() {}
};
struct Derived2 : Base2 {};

int main() {
  Derived d1;
  Base& b1 = d1;

  Derived2 d2;
  Base2& b2 = d2;

  cout << type_id_with_cvr<decltype(b1)>().pretty_name() << '\n';
  cout << type_id_with_cvr<decltype(b2)>().pretty_name() << '\n';

  return EXIT_SUCCESS;
}

Ausgabe:

Base&
Base2&
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Verwandter Artikel - C++ Operator