Inicio > Programación, Resolución problemas > C++: Mezclando plantillas y herencia

C++: Mezclando plantillas y herencia

Viernes, 16 de julio de 2010 Dejar un comentario Ir a comentarios

Tras varios años usando C++ aún sigo sufriendo dolores de cabeza cuando me atasco con alguna cosilla como la que os comento a continuación. Estoy desarrollando una librería en la que estoy usando bastante las plantillas y la herencia para intentar abstraer las cosas lo máximo posible. Pues bien, al intentar crear una clase plantilla derivada que heredaba comportamiento de otra clase plantilla me he encontrado con la sorpresa de que el compilador me decía que la clase derivada no tenía visibilidad sobre los miembros de la clase base. La solución a este problema es muy sencilla y os la comento a continuación.

Para ver todo esto de forma más gráfica os voy a dejar un código muy sencillo para que veáis de los mensajes de error que me lanzaba el compilador. Si intentáis compilar el siguiente código

#include <iostream>
#include <cstdlib>

using namespace std;

template <typename T>
class base
{
public:
  base(){}
protected:
  T _x;
};

template <typename T>
class derivada : public base<T>
{
  public:
    derivada(T x){_x = x;}
};

int main ()
{
  derivada<int> object(5);
  return EXIT_SUCCESS;
}				/* ----------  end of function main  ---------- */

El compilador debería mostraros un mensaje de error como el siguiente:

.../herencia_templates.cpp: In constructor ‘derivada<T>::derivada(T)’:
.../herencia_templates.cpp:19: error: ‘_x’ was not declared in this scope
make[2]: *** [CMakeFiles/herencia_templates.dir/herencia_templates.cpp.o] Error 1
make[1]: *** [CMakeFiles/herencia_templates.dir/all] Error 2

El problema parece ser que dentro de la clase derivada el miembro _x no depende del parámetro de plantilla T, por lo que _x es conocido como un nombre nodependiente. Por otra parte, la clase base (base<T&gt ;) es dependiente del parámetro de plantilla T, por lo que a base<T> se le llama nombre dependiente. La regla es que el compilador no mirará en clases de nombre dependiente (base<T&gt ;) cuando se estén buscando nombres nodependientes (_x). Esto no significa que la herencia no funcione. La clase derivada sigue heredando de la clase base, pero tenemos que especificar las llamadas a las variables de la clase base de alguna de las siguientes formas:

  • Cambiar la llamada a _x por this->_x. Debido a que this es siempre implícitamente dependiente en la plantilla, this->_x es dependiente.
  • Cambiar la llamada a _x por base<T>::_x.

Read this post where I found the solution.

GD Star Rating
loading...
C++: Mezclando plantillas y herencia, 10.0 out of 10 based on 2 ratings
Share
  1. Sin comentarios aún.
  1. Sin trackbacks aún.