Universidade Tecnolgica Federal do Paran UTFPR Campus Curitiba
Universidade Tecnológica Federal do Paraná UTFPR – Campus Curitiba Orientação a Objetos Programação em C++ Grupo de Slides 10 – Parte B: Utilização efetiva e desacoplada de Lista encadeada com templates Prof. Dr. Jean Marcelo SIMÃO Aluno monitor (2013): Fabiano Cezar Domingos 1
Melhorando a solução apresentada no grupo de slides 10 – Parte A. . . 2
template<class TIPO> class Elemento { private: Elemento<TIPO>* p. Proximo; Elemento<TIPO>* p. Anterior; TIPO* p. Info; //char nome[150]; public: Elemento ( ); ~Elemento ( ); void set. Proximo ( Elemento<TIPO>* p. P ); Elemento<TIPO>* get. Proximo ( ); void set. Anterior ( Elemento<TIPO>* p. A ); Elemento<TIPO>* get. Anterior ( ); void set. Info ( TIPO* p. I ); TIPO* get. Info ( ); Elemento. h Atributo nome da classe Elemento não deve existir. Deve-se evitar a replicação de dados! Dados necessários para uma posterior listagem devem ser obtidos através do ponteiro p. Info. //void set. Nome ( char* n ); //char* get. Nome ( ); }; 3
Elemento. h template<class TIPO> Elemento<TIPO>: : Elemento ( ) { p. Proximo = NULL; p. Anterior = NULL; p. Info = NULL; } template<class TIPO> Elemento<TIPO>: : ~Elemento ( ) { p. Proximo = NULL; p. Anterior = NULL; p. Info = NULL; } template<class TIPO> void Elemento<TIPO>: : set. Proximo ( Elemento<TIPO>* p. P ) { p. Proximo = p. P; } template<class TIPO> Elemento<TIPO>* Elemento<TIPO>: : get. Proximo ( ) { return p. Proximo; } template<class TIPO> void Elemento<TIPO>: : set. Anterior ( Elemento<TIPO>* p. A ) { p. Anterior = p. A; } template<class TIPO> Elemento<TIPO>* Elemento<TIPO>: : get. Anterior ( ) { return p. Proximo; } template<class TIPO> void Elemento<TIPO>: : set. Info (TIPO* p. I ) { p. Info = p. I; } template<class TIPO> TIPO* Elemento<TIPO>: : get. Info() { return p. Info; } 4
template<class TIPO> class Lista { private: Elemento<TIPO>* p. Primeiro; Elemento<TIPO>* p. Atual; Lista. h public: Lista ( ); ~Lista ( ); void inicializa ( ); void limpar(); bool inclua. Elemento ( Elemento<TIPO>* p. Elemento ); bool inclua. Info (TIPO* p. Info ); //void liste. Infos ( ); A Lista template não deve possuir métodos para listar os seus dados. Não há como generalizar os algoritmos de listagem. Elemento<TIPO>* getp. Primeiro(); Elemento<TIPO>* getp. Atual(); }; 5
Lista. h template<class TIPO> Lista<TIPO>: : Lista ( ) { inicializa ( ); } template<class TIPO> void Lista<TIPO>: : limpar ( ) { Elemento<TIPO>* paux 1; Elemento<TIPO>* paux 2; template<class TIPO> Lista<TIPO>: : ~Lista ( ) { limpar(); } paux 1 = p. Primeiro; paux 2 = paux 1; while (paux 1 != NULL) { paux 2 = paux 1 ->get. Proximo(); delete (paux 1); paux 1 = paux 2; } template<class TIPO> void Lista<TIPO>: : inicializa ( ) { p. Primeiro = NULL; p. Atual = NULL; } template<class TIPO> Elemento<TIPO>* Lista<TIPO>: : getp. Primeiro() { return p. Primeiro; } template<class TIPO> Elemento<TIPO>* Lista<TIPO>: : getp. Atual() { return p. Atual; } 6
Lista. h template<class TIPO> bool Lista<TIPO>: : inclua. Info (TIPO *p. Info ) { if (NULL != p. Info) { template<class TIPO> bool Lista<TIPO>: : inclua. Elemento ( Elemento<TIPO>* p. Elemento ) { if (NULL != p. Elemento) { Elemento<TIPO>* p. Elemento = NULL; if (NULL == p. Primeiro) { p. Primeiro = p. Elemento; // p. Primeiro->set. Anterior ( NULL ); // p. Primeiro->set. Proximo ( NULL ); p. Atual = p. Primeiro; } else { p. Elemento->set. Anterior ( p. Atual ); //p. Elemento->set. Proximo ( NULL ); p. Atual->set. Proximo ( p. Elemento ); p. Atual = p. Atual->get. Proximo ( ); } return true; p. Elemento = new Elemento<TIPO>(); p. Elemento->set. Info (p. Info); inclua. Elemento (p. Elemento); return true; } else { printf ( "Erro, elemento nulo(a) na lista. n" ); } else { cout << "Erro, elemento nulo na lista. " << endl; return false; } } } 7
Lista. Alunos. h class Lista. Alunos { private: //template class Lista< Aluno > LTAlunos; public: Lista. Alunos(); ~Lista. Alunos(); void limpa. Lista(); void inclua. Aluno(Aluno* pa); void liste. Alunos(); void liste. Alunos 2(); void grave. Alunos(); void recupere. Alunos(); }; A classe Lista. Alunos armazenará os apontamentos de aluno por meio de uma Lista template parametrizada com Aluno. Os métodos limpar() e inclua. Aluno() chamam diretamente os métodos da Lista template, visto que o código é generalizado. Já o algoritmos de listagem para os Alunos são específicos e são definidos nesta classe. 8
Lista. Alunos: : Lista. Alunos() { } Lista. Alunos: : ~Lista. Alunos() { limpa. Lista(); } Lista. Alunos. cpp void Lista. Alunos: : liste. Alunos() { Elemento<Aluno>* p. El. Aux = NULL; Aluno* p. Al. Aux = NULL; p. El. Aux = LTAlunos. getp. Primeiro(); while (NULL != p. El. Aux) { p. Al. Aux = p. El. Aux->get. Info(); cout << " Aluno " << p. Al. Aux->get. Nome() << " com RA " << p. Al. Aux->get. RA() << ". " << endl; p. El. Aux = p. El. Aux->get. Proximo(); } void Lista. Alunos: : limpa. Lista() { LTAlunos. limpar(); } void Lista. Alunos: : inclua. Aluno ( Aluno* pa ) { if ( NULL != pa ) { LTAlunos. inclua. Info(pa); } else { cout << "Erro! Aluno não includes. "; cout << "Ponteiro Aluno inválido. " << endl; } } } void Lista. Alunos: : liste. Alunos 2() { Elemento<Aluno>* p. El. Aux = NULL; Aluno* p. Al. Aux = NULL; p. El. Aux = LTAlunos. getp. Atual(); while (NULL != p. El. Aux) { p. Al. Aux = p. El. Aux->get. Info(); cout << " Aluno " << p. Al. Aux->get. Nome() << " com RA " << p. Al. Aux->get. RA() << ". " << endl; p. El. Aux = p. El. Aux->get. Anterior(); } void Lista. Alunos: : grave. Alunos() {…} void Lista. Alunos: : recupere. Alunos() {…} } 9
class Disciplina { private: int id; int cont_alunos; int numero_alunos; char nome[150]; char area_conhecimento[150]; Departamento* Depto. Associado; Lista. Alunos Obj. LAlunos; public: Disciplina(int i, int na = 45, char* ac = ""); ~Disciplina(); void set. Id(int i); int get. Id(); void set. Nome(char* n); char* get. Nome(); void set. Departamento(Departamento* d); Departamento* get. Departamento(); void inclua. Aluno(Aluno* pa); void liste. Alunos(); void liste. Alunos 2(); }; Disciplina. h A classe Disciplina irá gerenciar os seus ponteiros de Aluno por meio de Obj. LAlunos. Como os métodos de inclusão e listagem já foram definidos na classe Lista. Alunos, basta chamá-los diretamente. 10
Disciplina. cpp Disciplina: : Disciplina(int i, int na, char* ac) { id = i; cont_alunos = 0; numero_alunos = na; Depto. Associado = NULL; strcpy (area_conhecimento, ac ); } Disciplina: : ~Disciplina() { Depto. Associado = NULL; } … void Disciplina: : liste. Alunos() { cout << "nn. Alunos matriculados na disciplina " << area_conhecimento << ": "<< endl; Obj. LAlunos. liste. Alunos(); } void Disciplina: : liste. Alunos 2() { cout << "nn. Alunos matriculados na disciplina " << area_conhecimento << ": "<< endl; Obj. LAlunos. liste. Alunos 2(); } void Disciplina: : inclua. Aluno ( Aluno* pa ) { if (NULL != pa) { if ( ( cont_alunos < numero_alunos ) || ( -1 == numero_alunos)) { Obj. LAlunos. inclua. Aluno(pa); cont_alunos++; } else { cout << "Aluno não incluído. “ << "Turma já lotada em " << numero_alunos << " alunos. " << endl; } } else { cout << "Erro! Aluno não incluído. " << "Ponteiro Aluno inválido. " << endl; } } 11
12
Exercícios Propostos a) Substituir todas as outras listas ‘específicas’ elaboradas nas versões anteriores do ‘sistema exemplo’, por ‘instâncias’ de listas cujo cerne provenha de gabarito ou template desenvolvido para o tratamento de listas. b) Estender em classe especializada cada lista baseada em template para que suas instâncias tenham a ‘capacidade’ de gravar e recuperar as informações incluídas nela. Neste sentido, por exemplo, a classe Lista. Alunos, seria derivada em Lista. Alunos. Gravadora. c) Retomando um exercício anterior: - Elaborar uma solução para armazenar as notas (1 a parcial, 2 a parcial e final) e número de faltas de cada aluno em cada disciplina. 13
Exercícios Suplementares • 1) Conforme o subsequente grupo de Slides 12, fazer com que Elemento<Tipo> seja uma classe aninhada (privada) de Lista<Tipo>. – Exemplo de classe Lista template com classe Elemento aninhada disponível em: http: //www. dainf. ct. utfpr. edu. br/~jeansimao/Programacao. Avancada/Prog. Avancada. htm • Vide ali exemplo de prova disponível. • 2) Substituir o objeto de Lista template LTAlunos na classe Lista. Alunos por um vector ou list da STL, seguindo o grupo de Slides 16. 14
- Slides: 14