Disponible la nueva versión "donationware" 7.3 de OrganiZATOR
Descubre un nuevo concepto en el manejo de la información.
La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aquí.

Curso C++

[Home]  [Inicio]  [Índice]


Técnica manejador-cuerpo

Ejemplo:

El programa muestra un ejemplo esquemático de aplicación de la técnica manejador-cuerpo en la que un manejador sirve para acceder a diversos objetos que responden a la misma interfaz.  Por supuesto se trata de un ejemplo esquemático y muy incompleto, pero ilustra claramente los principios de esta técnica.

#include <iostream>
using namespace std;

class Body {              // Superclase abstracta
  friend class Handle;
  protected:
  virtual void funcB() =0;
  virtual ~Body();        // destructor virtual!!
};

Body::~Body() { cout << "Destruyendo Objeto Body\n"; }

class B1 : public Body {  // implementación-1
  friend class Handle;
  void funcB() { cout << "Objeto B1\n"; }
  ~B1() { cout << "Destruyendo Objeto B1\n"; }
};
class B2 : public Body {  // implementación-2
  friend class Handle;
  void funcB() { cout << "Objeto B2\n"; }
  ~B2() { cout << "Destruyendo Objeto B2\n"; }
};

class Handle {            // manejador
  public:
    Handle (int n=0);     // constructor por defecto
    void funcH();         // método público
    ~Handle();            // destructor
  private:
    Body* bPtr;
};

void Handle::funcH() { bPtr->funcB(); }

Handle::Handle(int n) {   // definición del constructor
  if (n == 0) bPtr = new B1;
  else        bPtr = new B2;
}

Handle::~Handle() {       // definición del destructor
  cout << "Destruyendo Handle\n";
  delete bPtr;            // L.42:
}

int main() {              // =================
  {
    Handle h1(1);         // M2:
    h1.funcH();           // M3:
    Handle h2;            // M4:
    h2.funcH();           // M5:
  }                       // M6:
  return 0;
}

Salida:

Objeto B2
Objeto B1
Destruyendo Handle
Destruyendo Objeto B1
Destruyendo Objeto Body
Destruyendo Handle
Destruyendo Objeto B2
Destruyendo Objeto Body

Comentario:

El ejemplo muestra una superclase abstracta Body, de la que derivan dos implementaciones distintas: B1 y B2. El manejador Handle contiene un método público funcH que accede a las funciones de la implementación a través de un puntero bPtr a la superclase. Observe que es el propio manejador el que crea instancias de la implementación a través de su constructor, y el que se encarga después de destruirlas con su destructor.

Las salidas 1 y 2 son debidas a las sentencias M3 y M5. El resto de salidas se originan al salir de ámbito los objetos automáticos h1 y h2, y constituyen una magnífica muestra del proceso seguido en la destrucción de objetos.

Al llegar a M6 son invocados automáticamente los destructores  ~Handle() de los objetos h1 y h2, que invocan a su vez a la destrucción del objeto señalado por el puntero bPtr.

La sentencia L.42:

delete bPtr;            // L.42:

invoca a su vez al destructor del objeto ( 4.9.20a), de forma que son invocados los destructores ~B1() y ~B2(). A continuación, como las clases B1 y B2 no disponen de ninguna versión sobrecargada del operador delete(), se invoca la versión global ::operator delete(bPtr).  Recordemos que en la destrucción de objetos pertenecientes a jerarquías de clases, los destructores son invocados en orden inverso en que fuero invocados los constructores, resultando que las invocaciones de los destructores ~B1() y ~B2() son seguidas de sendas invocaciones al destructor ~Body() de la superclase.

Observe que la única acción que puede realizar explícitamente el usuario sobre los objetos Body es la invocación de la función Handle::funcH().  El resto de acciones, incluyendo la creación de objetos Bn y su destrucción, son realizadas automáticamente por el manejador Handle a través de sus constructores y destructores.