15.2. Upcasting

En el Capítulo 14 se vió como un objeto puede ser usado como un objeto de su propio tipo o como un objeto de su tipo base. Además el objeto puede ser manejado a través de su tipo base. Tomar la dirección de un objeto (o un puntero o una referencia) y tratarlo como la dirección de su tipo base se conoce como upcasting [74] debido al camino que se genera en los árboles de herencia que se suelen pintar con la clase base en la cima.

También se vió surgir un problema el cuál está encarnado en el siguiente código:

//: C15:Instrument2.cpp
// Inheritance & upcasting
#include <iostream>
using namespace std;
enum note { middleC, Csharp, Eflat }; // Etc.

class Instrument {
public:
  void play(note) const {
    cout << "Instrument::play" << endl;
  }
};

// Wind objects are Instruments
// because they have the same interface:
class Wind : public Instrument {
public:
  // Redefine interface function:
  void play(note) const {
    cout << "Wind::play" << endl;
  }
};

void tune(Instrument& i) {
  // ...
  i.play(middleC);
}

int main() {
  Wind flute;
  tune(flute); // Upcasting
} ///:~

Listado 15.1. C15/Instrument2.cpp


La función tune() acepta (por referencia) un Instrument, pero también acepta cualquier cosa que derive de Instrument. En el main(), se puede ver este comportamiento cuando se pasa un objeto Wind a afinar() sin que se necesite ningún molde. La interfaz de Instrument tiene que existir en Wind, porque Wind hereda sus propiedades de Instrument. Moldear en sentido ascendente (Upcasting) de Wind a Instrument puede "reducir" la interfaz, pero nunca puede ser menor que la interfaz de Instrument.

Los mismos argumentos son ciertos cuando trabajamos con punteros; la única diferencia es que el usuario debe indicar la dirección de los objtos de forma explícita cuando se pasen a una función.



[74] N del T: Por desgracia upcasting es otro de los términos a los que no he encontrado una traducción convincente (¿¿amoldar hacia arriba??) y tiene el agravante que deriva de una expresión ampliamente usada por los programadores de C (¿Quién no ha hecho nunca un cast a void* ;-) ?. Se aceptan sugerencias.