Implementieren Sie statischen Polymorphismus in C++

Syed Hassan Sabeeh Kazmi 12 Oktober 2023
  1. Verstehen Sie seltsam wiederkehrende Vorlagenmuster, um den Mechanismus des statischen Polymorphismus in C++ zu lernen
  2. Policy-Based Design verstehen, um die Nützlichkeit des statischen Mechanismus in C++ kennenzulernen
  3. Implementieren Sie statischen Polymorphismus mit früher Bindung, Überladung oder parametrischem Polymorphismus in C++
Implementieren Sie statischen Polymorphismus in C++

Der statische Polymorphismus kann primär im Kontext von C++ interpretiert werden. In diesem Tutorial erfahren Sie, wie wichtig, nützlich und wie Sie statische Polymorphie in C++ implementieren.

Die std:sort-Funktion von C++ ist statisch polymorph wegen ihrer Abhängigkeit von objektbereitgestellten Schnittstellen (Objekte, die sich wie Iterationen verhalten).

Weiterhin kann das genaue Verhalten bereitgestellter Iterationen (Objekte) unter der Schnittstelle in der Kompilierzeit bestimmt werden.

Verstehen Sie seltsam wiederkehrende Vorlagenmuster, um den Mechanismus des statischen Polymorphismus in C++ zu lernen

Das Implementieren von statischem Polymorphismus ist ein guter Codierungsstil. Dazu müssen Sie seine Mechanik über CRTP lernen. Es ist eine Tatsache, dass Sie etwas Flexibilität Ihres C++-Programms zugunsten der Geschwindigkeit opfern müssen (durch statischen Polymorphismus).

Es zeigt technisches polymorphes Verhalten, erreicht andere Ziele als seine anderen Typen und entscheidet, welches Stück Code ausgeführt und priorisiert werden soll, basierend auf dem Typ von etwas.

Darüber hinaus sind Implementierungen erforderlich, die zu einer Aufblähung der Binärcodegröße und einer Inspektion in jeder Übersetzungseinheit führen können, damit der Compiler die Implementierung verstehen kann.

#include <iostream>

template <class Self>
struct Primary {
  Self& self() { return static_cast<Self&>(*this); }

  // an algorithm to perform some function
  int basic_function(int x) {
    self().prologue();
    if (x > 42) x = self().downsize(x);
    x = self().crunch(x);
    self().epilogue();
    return x;
  }

  void prologue() {}

  int downsize(int x) { return x % 42; }

  int crunch(int x) { return -x; }

  void epilogue() {}
};

struct secondary_Derived : Primary<secondary_Derived> {
  int downsize(int x) {
    while (x > 42) x /= 2;
    return x;
  }

  void epilogue() {
    std::cout << "CRTP__ \n"
              << "Process complete! \n";
  }
};

int main() {
  secondary_Derived obj_Dri;
  std::cout << obj_Dri.basic_function(420);
}

Ausgang:

CRTP__
Process complete!
-26

Das CRTP ermöglicht es der Basisklasse, Informationen oder Daten in Bezug auf die abgeleitete Klasse bereitzustellen, und ihre Mehrheit der Anwendungsfälle stellt dasselbe dar; B. Boosts iterator_facade.

Die Signaturen ist eine Member-Funktion von CRTP und Dinge wie DerivedClass operator++() {/* Return *this after incrementation */} werden von dieser Member-Funktion abgeleitet.

Falls Ihr C++-Code ein polymorphes Ausgabeverhalten erfordert, sollte es von std::sstream vs. std::fstream vs. std::cout (auch wenn sein Typ nicht angegeben ist) polymorph und von ostream abgeleitet sein. Da CRTP eine Form der F-gebundenen Quantifizierung ist, wird sie als F-gebundener Polymorphismus bezeichnet.

Es ermöglicht das Erreichen virtueller Funktionen ohne die Kosten der Flexibilität und wird manchmal als simuliertes dynamisches Binden bezeichnet.

Windows STL- und WTL-Bibliotheken verwenden diese Funktion, und der Barton-Nackman trick ist eine ähnliche Verwendung von statischem Polymorphismus, der manchmal als eingeschränkte Vorlagenerweiterung bezeichnet wird, bei der gemeinsame Funktionen in einer Basisklasse platziert werden können, die den C++-Code minimiert Redundanz.

Policy-Based Design verstehen, um die Nützlichkeit des statischen Mechanismus in C++ kennenzulernen

Dies ist eine der äußerst leistungsfähigen Techniken, um statischen Polymorphismus in C++ zu erreichen. Im modernen C++-Design ist die richtlinienbasierte Klasse oder richtlinienbasierte Programmierung ein Entwurfsansatz, der auf einem Idiom für C++ basiert, das als Richtlinien bekannt ist.

Die Kompilierzeitvariante des Strategiemusters erhöht die Modularität und hebt orthogonale Entwurfsentscheidungen hervor.

Es definiert das Verhalten einzelner Klassen auf einem relativ niedrigen Niveau, das Innovation darstellt, während das Zusammensetzen von Softwarekomponenten aus austauschbaren Modulen alles andere als ein neues Konzept ist.

#include <windows.h>

#include <iostream>

struct color_code {
  void pri_color() { this->reveal_colorCode(); }

  void reveal_colorCode() {
    std::cout << "The color code is revealed!" << std::endl;
  }
};

struct banner_code {
  void pri_color() {
    std::cout << "The banner code is revealed to the officials!" << std::endl;
  }
};

template <class code_type>

class Info : public code_type {
 public:
  void code_implementation() { code_type::pri_color(); }
};

int main() {
  Info<color_code> lordcommander;
  lordcommander.code_implementation();

  Info<banner_code> kingslayer;
  kingslayer.code_implementation();
  return 0;
}

Ausgang:

The color code is revealed!
The banner code is revealed to the officials!

Es ermöglicht Ihnen, Muster für die Kompilierzeit neu zu interpretieren (z. B. Vorlagenmethodenmuster), sodass die Hauptklasse über einen Skelettalgorithmus verfügt, der die entsprechenden Funktionen einzelner Richtlinien (an Anpassungspunkten) aufruft.

Im Allgemeinen erfordern diese Designs keine Vererbung, und die meisten ihrer Funktionen spiegeln statisches polyphormisches Verhalten wider.

Implementieren Sie statischen Polymorphismus mit früher Bindung, Überladung oder parametrischem Polymorphismus in C++

Seine Objektmethoden werden zur Kompilierzeit aufgerufen und normalerweise mithilfe des Operators und der Funktionsüberladung implementiert.

Das Überladen von Methoden ist ein Polymorphismus zur Kompilierzeit, bei dem mehr als eine Methode denselben Namen, aber unterschiedliche Parameterlisten und -typen haben kann.

Es verbessert die Leistung, da seine Methoden zur Kompilierzeit bekannt sind, was die Ausführung beschleunigt, aber zu einer geringeren Flexibilität bei der Implementierung von Lösungen führt.

Das Überladen von Funktionen und das Überladen von Operatoren spiegeln das Verhalten des statischen Polymorphismus wider, da es eine Überladungseinrichtung bereitstellt, um die Funktionalität des Codes zu erweitern.

#include <windows.h>

#include <iostream>

// parametric polymorphism
template <class T>

T max(T a, T b) {
  return a > b ? a : b;
}

// early binding | static binding
class Base {
 public:
  void show() { std::cout << "\nIn Base \n"; }
};

class Derived : public Base {
 public:
  void show() { std::cout << "In Derived \n"; }
};

// override
void swap(int* a, int* b){

};

void swap(double* a, double* b){

};

int main() {
  int x = 10, y = 20;
  double a = 1.2, b = 3.4;

  // overloading | as static polymorphism
  swap(&x, &y);  // swap(int,int)
  swap(&a, &b);  // swap(double, double)

  // parametric polymorphism | as static polymorphism
  std::cout << ::max(9, 5) << std::endl;

  std::string foo("kingslayer"), bar("widow'swale");
  std::cout << ::max(foo, bar) << std::endl;

  // early binding or static binding | as static polymorphism
  Base* bp = new Derived;
  bp->show();

  return 0;
}

Ausgang:

9
widow'swale

In Base

Ein UML-Diagramm kann nicht direkt beschreiben, wie Polymorphismus gehandhabt wird, kann aber zumindest teilweise entweder statisch oder dynamisch implementiert werden (abhängig von der statischen Polymorphismus-Abhängigkeit des OOP-Modells).

Es ist möglich, die Auswirkungen indirekter Aufrufe auf die Leistung zu beseitigen, wenn das Verhalten des statischen Polymorphismus eher zur Kompilierzeit als zur Laufzeit auftritt.

Am wichtigsten ist, dass die Leistung der Hauptvorteil des statischen Polymorphismus ist, und PBD (Policy Based Design) und CRTP (Curiously Recurring Template Pattern) sind perfekte Beispiele, die zeigen, wie extrem leistungsfähig die Technik ist.

Es stellt dem Compiler und Optimierer Unmengen von kritisch wichtigen Informationen zur Verfügung, kann Annahmen zur Kompilierzeit überprüfen und unter kritischen Optionen für die Ausführung des Programms auswählen.

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub