Verwenden von vs typedef in C++

Jay Shaw 12 Oktober 2023
  1. das Schlüsselwort using in C++
  2. das Schlüsselwort typedef in C++
  3. Verwendung von typedef und using beim Definieren von Templates
  4. Abschluss
Verwenden von vs typedef in C++

Dieser Artikel versucht zwischen typedef und using zu unterscheiden. In der funktionalen C++-Programmierung haben diese Schlüsselwörter denselben Zweck und dieselbe Semantik, sodass zwischen ihnen nur ein sehr schmaler Unterschied besteht.

Dieser Artikel erklärt die Schlüsselwörter in verschiedenen Kontexten, um sicherzustellen, dass der Leser versteht, was diese Schlüsselwörter bewirken und welche Unterschiede zwischen typedef und using bestehen.

das Schlüsselwort using in C++

Das Verständnis des Schlüsselworts using im Gegensatz zu typedef ist wichtig, um die Unterschiede zwischen typedef und using zu lernen.

Es wird verwendet, um Objekte in den aktuellen Umfang des Programms zu bringen. Dies bedeutet, dass es als Zugriffstool verwendet werden kann, um Spezifizierer aus C++ zu holen.

Schauen wir uns ein Beispiel an.

#include <iostream>

int main() {
  using std::cout;
  using std::string;

  int a = 56;
  cout << a;
  return 0;
}

Ausgang:

56

Hier wird das Schlüsselwort using verwendet, um auf Bezeichner wie cout und string aus dem Namensraum zuzugreifen und sie in den Gültigkeitsbereich des Programms zu bringen.

In ähnlicher Weise kann using auch verwendet werden, um auf andere Spezifizierer zuzugreifen oder den gesamten Namensraum zu bringen, indem - using namespace as std verwendet wird. Dadurch wird der gesamte Namensraum in den Gültigkeitsbereich des Programms gebracht, und auf jeden Bezeichner kann mit std zugegriffen werden.

Beispiel für Keyword using

Das folgende Code-Snippet erstellt eine Klasse Parent mit einer öffentlichen Methode add mit zwei Integer-Variablen a und b als Parameter. Die Methode add gibt die Summe der beiden Variablen aus.

Die Klasse child leitet die Klasse Parent im geschützten Modus ab, was bedeutet, dass alle Mitglieder der Klasse Parent als geschützte Mitglieder geerbt werden.

Innerhalb der Funktion main wird eine Instanz des Objekts mit der Klasse Child erstellt und die Methode add mit diesem Objekt abgeleitet.

#include <iostream>
using namespace std;
class Parent {
 public:
  void add(int a, int b) { cout << "Result = " << a + b << endl; }
};
class Child : protected Parent {
 public:
  using Parent::add;
};
int main() {
  Child obj;
  obj.add(15, 30);
  return 0;
}

Ausgang:

Result = 45

Hier wird mit dem Schlüsselwort using auf die Methode add der Klasse Parent über deren Klasse Child zugegriffen.

Implementieren Sie Schleifen mit dem Schlüsselwort using in C++

Die Syntax hier implementiert die for-Schleife durch using.

for (using i = int; i{} != 0;) {
  i++;
}

Bei bereichsbasierten Schleifen wird using wie folgt verwendet:

std::vector<int> v{1, 2, 3};
for (using Foo = int; Foo f : v) {
  (void)f;
}

Switch Case-Anweisungen mit dem using-Schlüsselwort in C++

In switch case-Anweisungen wird using implementiert als:

if (using Foo = int; true) {
  (void)Foo{};
}
switch (using Foo = int; 0) {
  case 0:
    (void)Foo{};
}

das Schlüsselwort typedef in C++

Das Schlüsselwort typedef hat die Funktion, einen Typ mit einem benutzerdefinierten Namen zu benennen. Das bedeutet, dass für einen bestehenden Datentyp ein Alias eingeführt werden kann.

In diesem Abschnitt sind große Unterschiede zwischen typedef und using zu erkennen.

Das folgende Programm erklärt dieses Konzept deutlich.

#include <stdio.h>
#include <string.h>

typedef struct Books {
  char title[50];
  char author[50];
  char subject[100];
  int book_id;
} Book;

Es wird eine struct-Klasse Book eingeführt, die vier Variablen hat. Diese vier Variablen werden mit typedef als neuer Datentyp strukturiert, und dieser Typ erhält den Namen Book.

Innerhalb der Klasse main muss ein neues Objekt erstellt werden, um auf den Typ Book zuzugreifen und seine Variablen abzurufen (je nach Anforderung).

Es ist zu beobachten, dass die einzelnen Variablen mit der Syntax Objektname.Variablenname,"Eingabe" aufgerufen werden. Sobald diese Variablen mit Daten versehen sind, werden sie mit der gleichen Methode gedruckt, mit der sie aufgerufen wurden.

int main() {
  Book book;

  strcpy(book.title, "Typedef vs using");
  strcpy(book.author, "JS");
  strcpy(book.subject, "C Programming");
  book.book_id = 6495407;

  printf("Book title : %s\n", book.title);
  printf("Book author : %s\n", book.author);
  printf("Book subject : %s\n", book.subject);
  printf("Book book_id : %d\n", book.book_id);

  return 0;
}

Ausgang:

Book title : Typedef vs using
Book author : JS
Book subject : C Programming
Book book_id : 6495407

Schleifen mit dem Schlüsselwort typedef in C++

Während der Schleifeniteration wird typedef mit der Syntax for (typedef (datatype)Function; Function{} != 0;) definiert.

for (typedef int i; i{} != 0;) {
  i++;
}

Während einer bereichsbasierten Schleifeniteration wird typedef verwendet als:

std::vector<int> v{1, 2, 3};
for (typedef int Foo; Foo f : v)
//   ^^^^^^^^^^^^^^^ init-statement
{
  (void)f;
}

Ein weiteres Beispiel für eine bereichsbasierte Schleife in einer 2-D-Matrix:

for (typedef struct {
       int x;
       int y;
     } P;
     auto [x, y] : {P{1, 1}, {1, 2}, {3, 5}}) {
  (void)x;
  (void)y;
}

Switch Case-Anweisungen mit dem typedef-Schlüsselwort in C++

Das Schlüsselwort typedef wird in switch case-Anweisungen verwendet, wie unten gezeigt.

if (typedef int Foo; true) {
  (void)Foo{};
}

switch (typedef int Foo; 0) {
  case 0:
    (void)Foo{};
}

Verwendung von typedef und using beim Definieren von Templates

Wir haben Unterschiede zwischen typedef und using aus dem Kontext der funktionalen Programmierung beobachtet. Ein weiterer wichtiger Teil, der verstanden werden muss, ist die Definition von Vorlagen.

In C++ hatten typedefs die Funktion, Aliase für Templates zu definieren. Es wird schon sehr lange verwendet, aber es wurde beobachtet, dass die Semantik von typedef nicht gut zu Templates passt.

Um das Problem zu lösen, wurde typedef abgeschrieben und using durchgeführt.

In den folgenden Beispielen werden die Unterschiede zwischen typedef und using im Zusammenhang mit der Definition von Templates diskutiert.

Aliasing-Template Mit typedef in C++

Beispiel 1:

Hier wurde ein Rechteck mit einer Länge von x und einer statischen Breite definiert, das mithilfe von Vorlagen mit einem Alias versehen werden muss.

<size_t N> ist eine Vorlage, die die Länge des Rechtecks speichert. Dimension hingegen ist ein Objekt, dem mittels typedef der Alias Rectangle gegeben wird.

Hier weist der Code dem Rectangle einen Alias von Dimension<N,1> zu, was bedeutet, dass das Objekt Dimension eine Länge und eine Breite haben wird. Hier hat das Objekt Dimension eine Länge <size_t N> und eine Breite von 1.

template <size_t N>
struct Rectangle {
  typedef Dimension<N, 1> type;
};

Dies impliziert, dass der Programmierer einen Einzelwertparameter, size_t N, an Rectangle übergeben muss. Der Compiler nimmt die übergebene Länge als Länge, während die Breite auf 1 gesetzt ist.

Die Syntax Rectangle<5>::int übergibt den ganzzahligen Wert 5 an das Objekt Dimension und entspricht dem Schreiben von Dimension<5,1>.

Die obigen Beispiele werden in der neueren C++-Version nicht mehr verwendet, da typedef abgewertet wird. Die Verwendung von using, um Templates einen Alias zu geben, ist einfacher als das obige Beispiel.

Beispiel 2:

Die Template-Klasse Match ist im Code-Snippet unten definiert. Diese Match-Klasse erhält ein Alias-Template MatchBox.

Die Klasse Match kann auch in Zukunft ersetzt werden.

template <typename U>
struct Match {};

template <typename U>
struct MatchBox {
  typedef Match<U> type;
};

MatchBox<int>::type variable;

template <typename V>
struct bar {
  typename MatchBox<V>::type_var_member;
}

Wenn eine Typabstraktion erforderlich ist, aber der Vorlagenparameter auch beibehalten werden muss, damit er in Zukunft bereitgestellt werden kann, ist dies die Art von Code, die geschrieben werden sollte.

Aliasing von Vorlagen mit dem Schlüsselwort using in C++

Beispiel 1:

Dieser Abschnitt zeigt die Unterschiede zwischen typedef und using im Kontext von Templates auf. Hier ist das Template <size_t N> das gleiche wie im typedef-Beispiel 1, das die Länge des Rechtecks speichert.

Statt struct zu verwenden, wird dem Objekt Dimension durch das Schlüsselwort using der Alias Rectangle zugewiesen. Dies geschieht auf die gleiche Weise wie die Zuweisung eines Operators.

Der Alias Rectangle hat nach Alias-Zuweisung N und 1 als Länge bzw. Breite.

template <size_t N>
using Rectangle = Dimension<N, 1>;

Es kann beobachtet werden, dass using eine verfeinerte Version von Aliasing bietet, die einfacher zu schreiben und zu implementieren ist. Die Lesbarkeit der hier verwendeten Syntax scheint verbessert, da sie nun eher der konventionellen Zuweisung von Variablen und Operatoren entspricht.

Beispiel 2:

In diesem Beispiel bleibt der Vorlagenparameter offen, sodass seine Angabe möglich bleibt. Im typedef-Beispiel erforderte dieser Vorgang mehrere Codezeilen. Aber die Syntax using reduziert Code und Komplexität.

template <typename U>
using MatchBox = Match < U

                             MatchBox<int>
                                 variable;
template <typename V>
struct bar {
  MatchBox<V> _var_member;
}

Die Verwendung des Schlüsselworts using zum Definieren eines Alias für Vorlagen ist viel einfacher als typedef, da der Vorgang dem Kopieren von Zuweisungen von Variablen ähnelt.

Abschluss

Dieser Artikel behandelt die Unterschiede zwischen den Schlüsselwörtern typedef und using in C++. Der Leser wird die grundlegenden Unterschiede und die Implementierung dieser Schlüsselwörter in verschiedenen Programmierkontexten verstehen.

Wir hoffen, dass dieser Artikel Ihnen bei Ihrer Lernreise geholfen hat.