Los templates tienen un tratamiento especial por parte del compilador, lo recomendable es que tengas definido el template en un archivo de cabecera y no en un archivo que será traducido a código objeto (cpp) ya que se pierde generalidad. Obviamente esto último confunde un poco, ya que si algo buscamos justamente es ocultar la implementación del código que, aunque parezca absurdo en el caso de los templates, no lo es, todo dependerá de necesidades específicas.
Solución 1 (recomendable)
Nodo.h
Código C++:
Ver original#ifndef NODO_H
#define NODO_H
#include <iostream>
template <class Q>
class Nodo{
private:
Q *MiDato;
Nodo<Q> *next;
public:
Nodo(Q nuevo){
next = NULL;
MiDato = new Q;
*MiDato = nuevo;
}
Nodo(void): MiDato(NULL), next(NULL) {}
~Nodo(void){
delete MiDato;
next = NULL;
}
void set_data(Q nuevo){
MiDato = new Q;
*MiDato = nuevo;
}
void set_next(Nodo<Q> *s) { next = s; }
const Q get_data(void) const { return *MiDato; }
Nodo<Q> *get_next(void) { return next; }
void ShowAll(void) const{
Nodo<Q> *aux = next;
std::cout << *MiDato << std::endl;
while(aux){
std::cout << aux->get_data() << std::endl;
aux = aux->get_next();
}
}
};
#endif // NODO_H
Lista.h
Código C++:
Ver original#ifndef LISTA_H
#define LISTA_H
#include "Nodo.h"
template <class Q>
class Lista{
private:
Nodo<Q> *inicio;
Nodo<Q> *final;
int tam;
public:
Lista(void): inicio(NULL), final(NULL), tam(0) {}
~Lista(void){
Nodo<Q> *aux = inicio;
if(!empty()){
while(inicio){
inicio = inicio->get_next();
delete aux;
aux = inicio;
}
}
final = NULL;
tam = 0;
}
void add(Q nuevo){
Nodo<Q> *aux = new Nodo<Q>(nuevo);
if(empty()){
inicio = aux;
}else{
final->set_next(aux);
}
final = aux;
tam++;
}
int get_tam(void) const { return tam; }
bool empty(void) const{
return (inicio == NULL);
}
void Mostrar(void) const { inicio->ShowAll(); }
};
#endif // LISTA_H
main.cpp
Código C++:
Ver original#include <iostream>
#include "Lista.h"
using namespace std;
int main(void){
Lista<int> Buena;
Lista<char> Mala;
for(int i = 10; i < 21; i++){
Buena.add(i);
}
Mala.add('M');
Mala.add('A');
Mala.add('L');
Mala.add('A');
cout << "Buena mide: " << Buena.get_tam() << endl;
Buena.Mostrar();
cout << "\nMala mide: " << Mala.get_tam() << endl;
Mala.Mostrar();
return 0;
}
Solución 2
Nodo.h
Código C++:
Ver original#ifndef NODO_H
#define NODO_H
template <class Q>
class Nodo{
private:
Q *MiDato;
Nodo<Q> *next;
public:
Nodo(Q nuevo);
Nodo(void);
~Nodo(void);
void set_data(Q nuevo);
void set_next(Nodo<Q> *s);
const Q get_data(void) const;
Nodo<Q> *get_next(void);
void ShowAll(void) const;
};
#endif // NODO_H
Nodo.cpp
Código C++:
Ver original#include <iostream>
#include "Nodo.h"
using namespace std;
template <class Q>
Nodo<Q>::Nodo(Q nuevo){
next = NULL;
MiDato = new Q;
*MiDato = nuevo;
}
template <class Q>
Nodo<Q>::Nodo(void): MiDato(NULL), next(NULL) {}
template <class Q>
Nodo<Q>::~Nodo(void){
delete MiDato;
next = NULL;
}
template <class Q>
void Nodo<Q>::set_data(Q nuevo){
MiDato = new Q;
*MiDato = nuevo;
}
template <class Q>
void Nodo<Q>::set_next(Nodo<Q> *s) { next = s; }
template <class Q>
const Q Nodo<Q>::get_data(void) const { return *MiDato; }
template <class Q>
Nodo<Q> *Nodo<Q>::get_next(void) { return next; }
template <class Q>
void Nodo<Q>::ShowAll(void) const{
Nodo<Q> *aux = next;
cout << *MiDato << endl;
while(aux){
cout << aux->get_data() << endl;
aux = aux->get_next();
}
}
template class Nodo<int>;
template class Nodo<char>;
Lista.h
Código C++:
Ver original#ifndef LISTA_H
#define LISTA_H
#include "Nodo.h"
template <class Q>
class Lista{
private:
Nodo<Q> *inicio;
Nodo<Q> *final;
int tam;
public:
Lista(void);
~Lista(void);
void add(Q nuevo);
int get_tam(void) const;
bool empty(void) const;
void Mostrar(void) const;
};
#endif // LISTA_H
Lista.cpp
Código C++:
Ver original#include <iostream>
#include "Lista.h"
template <class Q>
Lista<Q>::Lista(void): inicio(NULL), final(NULL), tam(0) {}
template <class Q>
Lista<Q>::~Lista(void){
Nodo<Q> *aux = inicio;
if(!empty()){
while(inicio){
inicio = inicio->get_next();
delete aux;
aux = inicio;
}
}
final = NULL;
tam = 0;
}
template <class Q>
void Lista<Q>::add(Q nuevo){
Nodo<Q> *aux = new Nodo<Q>(nuevo);
if(empty()){
inicio = aux;
}else{
final->set_next(aux);
}
final = aux;
tam++;
}
template <class Q>
int Lista<Q>::get_tam(void) const { return tam; }
template <class Q>
bool Lista<Q>::empty(void) const{
return (inicio == NULL);
}
template <class Q>
void Lista<Q>::Mostrar(void) const { inicio->ShowAll(); }
template class Lista<int>;
template class Lista<char>;
main.cpp
Código C++:
Ver original#include <iostream>
#include "Lista.h"
using namespace std;
int main(void){
Lista<int> Buena;
Lista<char> Mala;
for(int i = 10; i < 21; i++){
Buena.add(i);
}
Mala.add('M');
Mala.add('A');
Mala.add('L');
Mala.add('A');
cout << "Buena mide: " << Buena.get_tam() << endl;
Buena.Mostrar();
cout << "\nMala mide: " << Mala.get_tam() << endl;
Mala.Mostrar();
return 0;
}
Puedes consultar el siguiente
tema para entender la implementación de la solución 2.