Implementar polimorfismo estático en C++

Syed Hassan Sabeeh Kazmi 12 octubre 2023
  1. Comprender el patrón de plantilla curiosamente recurrente para aprender el mecanismo del polimorfismo estático en C++
  2. Comprender el diseño basado en políticas para conocer la utilidad del mecanismo estático en C++
  3. Implemente el polimorfismo estático mediante el enlace anticipado, la sobrecarga o el polimorfismo paramétrico en C++
Implementar polimorfismo estático en C++

El polimorfismo estático se puede interpretar principalmente en el contexto de C++. Este tutorial le enseñará la importancia, la utilidad y cómo implementar el polimorfismo estático en C++.

La función std:sort de C++ es estáticamente polimórfica debido a su dependencia de la interfaz proporcionada por el objeto (objetos que se comportan como iteraciones).

Además, el comportamiento exacto de las iteraciones proporcionadas (objetos) bajo la interfaz se puede determinar en el tiempo de compilación.

Comprender el patrón de plantilla curiosamente recurrente para aprender el mecanismo del polimorfismo estático en C++

Implementar polimorfismo estático es un buen estilo de codificación; para hacer esto, necesita aprender su mecánica a través de CRTP. Es un hecho que debe sacrificar algo de flexibilidad de su programa C++ por velocidad (a través del polimorfismo estático).

Muestra un comportamiento de polimorfismo técnico, logra diferentes objetivos que sus otros tipos y decide qué pieza de código ejecutar y priorizar en función del tipo de algo.

Además, requiere implementaciones que pueden dar como resultado un aumento del tamaño del código binario y la inspección en cada unidad de traducción para que el compilador pueda comprender la implementación.

#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);
}

Producción :

CRTP__
Process complete!
-26

El CRTP permite que la clase base proporcione información o datos en términos de la clase derivada y la mayoría de los casos de uso representan lo mismo; por ejemplo, iterator_facade de Boost.

Las firmas son una función miembro de CRTP y cosas como DerivedClass operator++() {/* Return *this after incrementation */} se derivan de esta función miembro.

En caso de que su código C++ requiera un comportamiento de salida polimórfico, debe derivarse de std::sstream vs std::fstream vs std::cout (aunque su tipo no está especificado) son polimorfismos y derivados de ostream. Como CRTP es una forma de cuantificación F-bound, se conoce como polimorfismo F-bound.

Permite el logro de funciones virtuales sin el costo de la flexibilidad y, a veces, se denomina “enlace dinámico simulado”.

Las bibliotecas STL y WTL de Windows usan esta función y el truco de Barton-Nackman es un uso similar del polimorfismo estático, que a veces se denomina expansión de plantilla restringida, donde la funcionalidad común se puede colocar en una clase base que minimiza el código C++ redundancia.

Comprender el diseño basado en políticas para conocer la utilidad del mecanismo estático en C++

Es una de las técnicas extremadamente poderosas para lograr polimorfismo estático en C++. En el diseño moderno de C++, la clase basada en políticas o la programación basada en políticas es un enfoque de diseño basado en una expresión de C++ conocida como políticas.

La variante de tiempo de compilación del patrón de estrategia aumenta la modularidad y destaca las decisiones de diseño ortogonal.

Define el comportamiento de clases individuales en un nivel relativamente bajo que representa innovación, mientras que ensamblar componentes de software a partir de módulos intercambiables está lejos de ser un concepto nuevo.

#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;
}

Producción :

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

Le permite reinterpretar patrones para el tiempo de compilación (por ejemplo, patrón de método de plantilla) para que la clase principal tenga un algoritmo esqueleto, que llama a las funciones apropiadas de políticas individuales (en puntos de personalización).

Generalmente, estos diseños no requieren herencia y la mayoría de sus funciones reflejan un comportamiento polifórmico estático.

Implemente el polimorfismo estático mediante el enlace anticipado, la sobrecarga o el polimorfismo paramétrico en C++

Sus métodos de objeto se invocan en tiempo de compilación y generalmente se implementan utilizando el operador y la sobrecarga de funciones.

La sobrecarga de métodos es un polimorfismo en tiempo de compilación en el que más de un método puede tener el mismo nombre pero diferentes tipos y listas de parámetros.

Mejora el rendimiento ya que sus métodos se conocen en tiempo de compilación, lo que hace que la ejecución sea más rápida pero conduce a una menor flexibilidad en la implementación de soluciones.

La sobrecarga de funciones y la sobrecarga de operadores reflejan el comportamiento del polimorfismo estático, ya que proporciona una función de sobrecarga para ampliar la funcionalidad del código.

#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;
}

Producción :

9
widow'swale

In Base

Un diagrama UML no puede describir directamente cómo se maneja el polimorfismo, pero puede implementarse al menos parcialmente de forma estática o dinámica (dependiendo de la dependencia del polimorfismo estático del modelo OOP).

Es posible eliminar el impacto en el rendimiento de las llamadas indirectas cuando el comportamiento del polimorfismo estático ocurre en tiempo de compilación en lugar de en tiempo de ejecución.

Lo que es más importante, el rendimiento es el beneficio principal del polimorfismo estático, y PBD (diseño basado en políticas) y CRTP (patrón de plantilla curiosamente recurrente) son ejemplos perfectos que resaltan cuán extremadamente poderosa es la técnica.

Proporciona toneladas de información de importancia crítica para el compilador y el optimizador, puede verificar suposiciones en el momento de la compilación y puede seleccionar entre opciones críticas para la ejecución del programa.

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