Mudanças entre as edições de "POO29705-2019-1"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
Linha 1 588: Linha 1 588:
 
[[Arquivo:DiagramaSequenciaAbrirPorta.png]]
 
[[Arquivo:DiagramaSequenciaAbrirPorta.png]]
  
=AULA 16 - Dia 14/06/2019 (projeto - Aula a sábado)=
+
=AULA 17 - Dia 14/06/2019 (projeto - Aula a sábado)=
  
 
==Objetivos==
 
==Objetivos==

Edição das 14h36min de 14 de junho de 2019

Professor

  • Eraldo Silveira e Silva (eraldo@ifsc.edu.br)

ALUNOS

  • Alfredo
  • Valmir

Avaliação

  • 1 Prova Formal
  • 1 Nota de Atividades
  • 1 Projeto

Link para PRG1

https://wiki.sj.ifsc.edu.br/index.php/Proposta_de_Aulas_de_Introdu%C3%A7%C3%A3o_a_Programa%C3%A7%C3%A3o_C

OBSERVAÇÃO

  • cada registro de aula coreesponde a 2HA.

AULA 1 (2ha)- Dia 25/02/2019

Plano de Ensino

  • Competências
    • Desenvolver Projetos Orientados a objetos
  • Bases Tecnológicas
    • Ciclos de desenvolvimento de software.
    • Qualidade de software.
    • A visão de objetos.
    • Projeto orientado a objetos com auxilio computacional e linguagem UML.
    • Programação orientada a objeto utilizando linguagem C++ ou Java.
    • Introdução a programação para WEB.
    • Acesso a banco de dados.

Revisão de Lógica de Programação e de Programação C

  • Livro: Estudo Dirigido Linguagem C - Manzano
  • gcc e gedit

Exemplo pg.46 do livro:

#include <stdio.h>

int main()
{
 int num1,num2,soma;

 printf("Entre com o primeiro número\n");
 scanf("%d", &num1);
 printf("Entre com o segundo número\n");
 scanf("%d", &num2);
 
 soma = num1 + num2;

 printf("Valor da soma é %d\n", soma);
}
  • Compilação
gcc ex1.c -o ex1

ATIVIDADES

  • Ler Cap.3 do Livro e fazer todos exercícios do final. Fazer commit no github - TAREFA 1
  • Ler Cap. 4.1, 4.2, 4.3 e 4.4.

AULA 2 - Dia 8/03/2019

OBJETIVOS

  • Instruções de Decisão C - revisão
  • Instruções de Repetição no C - revisão
  • Exemplo de controle de acesso

Material de Referência

ATIVIDADE

  • Finalizar leitura Cap.4 e começar a leitura Cap.5
  • Fazer execícios do final do Cap.4 e postar no github - TAREFA 2 (deadline 13/03)
  • Fazer execícios do final do Cap.5 e postar no github - TAREFA 3 (deadline 20/03)

AULA 3 - Dia 15/03/2019

OBJETIVOS

  • Revisão conceito de Arrays
  • Revisão de Funções

Exercício Inicial de Verificação

Computar a soma de N números inteiros a serem fornecidos no teclado usando o comando for. Mostrar o resultado.

Referências

https://wiki.sj.ifsc.edu.br/index.php/AULA_8_-_Programa%C3%A7%C3%A3o_1_-_Engenharia

https://wiki.sj.ifsc.edu.br/index.php/AULA_9_-_Programa%C3%A7%C3%A3o_1_-_Engenharia

https://wiki.sj.ifsc.edu.br/index.php/AULA_10_-_Programa%C3%A7%C3%A3o_1_-_Engenharia

Cap.6 e 7 do livro.

AULA 4 - Dia 22/03/2019

OBJETIVOS

  • O paradigma orientado a objetos (cap.1 Bezerra)
    • modelagem de sistemas de software;
    • paradigma OO:classes e objetos, mensagens e abstração
    • a UML
  • O pŕocesso de desenvolvimento de software (cap.2 Bezerra)
    • atividades típicas de um processo
    • participantes do processo
    • ciclos de vida
    • utilização da UML

AULA 5 - Dia 29/03/2019

OBJETIVOS

  • Discussão do Projeto Final
  • Apresentação da BeagleBone


  • Modelagem de Casos de Uso
  • Modelagem de Classes
  • Conceito de Associação e Generalização
  • Herança e Polimorfismo
  • Diagrama de Classes e Objetos
  • Exemplo: Sistema de Controle de Acesso

Referências

https://beagleboard.org/getting-started

AULA 6 - Dia 5/04/2019

  • Visão de Casos de Uso (discussão cap.4 do Bezerra)

TAREFA (Projeto - Fase 1)

  • Elaborar lista de requisitos do Projeto de Controle de Acesso
  • Elaborar Regra de Negócios
  • Elaborar Diagrama de Casos de Uso
    • Dividir os 14 requisitos em 2 mas propor um adicional para agregar valor.


TAREFA 2

  • Ler cap.5 do Bezerra.

AULA 7 - Dia 10/04/2019

OBJETIVOS

Parte 1

  • Introdução ao C++
  • Classes e Objetos no C++ (ver material Prof.Sobral)
    • Declaração de classes
    • Criação de objetos
    • Destruição de objetos
    • Um exemplo

Parte 2

  • Modelagem da Dinâmica do Sistema
  • Diagramas de Interação, Sequência e Colaboração
  • Exemplo: Controle de Acesso

Exemplo - A porta do sistema de controle de acesso

  • porta.h
class forma_porta {
 private:
  int estado; /* 0 se fechado e 1 se aberto */
  int tipoPorta; /* 0 porta de abrir, 1 de correr, 2 sanfonada */
  string ambienteDaPorta;
 public:
  forma_porta(string nome) {
    ambienteDaPorta = nome;
  }
  int lerEstado() {
      return estado;
  }
  void abrirPorta();
};
  • porta.cc
#include <cstring>
#include <iostream>
#include <stdio.h>

using namespace std;

#include "porta.h"

void forma_porta::abrirPorta()
{
  cout << "Abrir porta do ambiente " << ambienteDaPorta << "\n";
}

class forma_porta portaCad2("cad2");

int main()
{  
  portaCad2.abrirPorta();
}

Aula 12.04.19

Aulapoo 120419.jpg



Exercício

No exemplo anterior criar dois objetos para a porta do CAD1 e do CAD2. Criar um objeto adicional chamado Controlador para acionar estas portas.

Material de Referência

AULA 8 - Dia 26/04/2019

OBJETIVOS

])

Declaração de classes

Exercício: Implementar construtor/destrutor e métodos para acessar a classe que representa uma pessoa conforme indicado abaixo. Colocar a classe em um arquivo .h. Criar localmente duas pessoas e testar os métodos no main.

class pessoa {

private:
  string nome;
  string data_nasc;
  string cidade_nasc;
public:
  pessoa(string umNome, string umaData, string umaCidade);
  ~pessoa();
  string obtemNome();
  string obtemDataNasc();
  string obtemCidadeNasc();

}; </syntaxhighlight>

Criação/Destruição

https://wiki.sj.ifsc.edu.br/index.php/Introdu%C3%A7%C3%A3o_C%2B%2B#Cria.C3.A7.C3.A3o_de_objetos

Um exemplo de classe: vetor

https://wiki.sj.ifsc.edu.br/index.php/Introdu%C3%A7%C3%A3o_C%2B%2B#Um_exemplo

Material de Referência

AULA 9 - Dia 26/04/2019

OBJETIVOS

  • Passagem de parâmetros
  • Alocação dinâmica de memória: operadores new e delete
  • Templates


Lembrete da Avaliação sobre o Projeto

A3 - Projeto Final envolvendo UML e C++

     *Documentação: 30 %
     *Desempenho durante o desenvolvimento: 30%
     *Defesa: 40 %


Para organizar este processo vamos colocar as seguintes fases:

  • FASE (Sprint) 1 - Foco principal na Concepção (link github já repassado) - Diagramas de Caso de Uso, listas de requisitos funcionais, não funcionais e regras de negócio.
  • FASE 2 - Foco principal no Projeto - diagramas de classes
  • FASE 3 - Foco Principal no Projeto - diagramas de sequência
  • FASE 4 - Foco Principal Implementação de casos de usos selecionados
  • FASE 5 - Foco Principal Implementação de casos de usos selecionados
  • FASE 6 - Foco Principal Implementação de casos de usos selecionados
  • FASE 7 - Foco Principal Implementação de casos de usos selecionados
  • FASE 8 - Foco Principal Implementação de casos de usos selecionados
  • FASE 9 - Foco Principal Teste/Implantação
  • FASE 10 - Apresentação Final

Lembrete da Avaliação de Atividades

A A2 é baseada nas atividades repassadas em sala. Até o momento foram passadas 3 atividades de revisão do C. Elas não serão incluídas nesta avaliação. Pa fins de organização vou formalizar 5 atividades de POO-C++ nomeadas da forma:

  • Atividade POO-C++ 1
  • Atividade POO-C++ 2
  • Atividade POO-C++ 3
  • Atividade POO-C++ 4
  • Atividade POO-C++ 5

Atividade POO-C++ 1

NOTA: sempre organizar o código em .h e .cpp

  1. Implemente uma classe que representa um triângulo qualquer. A classe deve possuir um construtor que possibilite configurar os lados do mesmo.Ela deve possuir um método que retorne a área e o perímetro do triângulo além de 3 métodos para retornar e setar cada lado. Deve ser previsto um parâmetro booleano que indica se o triângulo é válido ou não. (depois veremos como poderia ser contornado este problema). Teste a criação de dois objetos no main(). Um deles deve ser criado com o operador new e outro como variável local. NÃO usar métodos inline. Prever também um método para imprimir todos os lados, a área e o perímetro, quando o triângulo for válido. Caso contrário imprimir mensagem de triângulo inválido. Se existir uma situação de triângulo inválido e for solicitado áreao ou perímetro, retornar -1,
  2. Implemente uma classe que representa o tempo. Da mesma forma que o anterior devem ser previstos construtor e métodos para manipular o tempo (hora de 0 a 23, minuto de 0 a 59 e segundo de 0 a 59). Fazer todos os métodos inline. Teste a classe criando dois objetos e mostrando o uso dos métodos.
    class Tempo {
      private:
         int hora;
         int minuto;
         int segundo;
      public:
         Tempo(int _hora, int _minuto, _segundo){};
         Tempo(){};
         void setTempo(int _hora, int _minuto, _segundo){}
         void getTempo(int &_hora, int &_minuto, int &_segundo); //depoi será mostrado como retornar valores ..
         void incrementTempo(); //incrementa em um segundo
         void printTempo(); //imprime tudo...
      
    };
    
  3. Implemente uma classe que representa um carro. Preveja um atributo que representa velocidade (ver nota de aula do Prof.Emerson Mello). Testar a classe no programa main.
  4. Implemente uma classe que representa um endereço. Coloque o máximo possível de informação. Preveja um atributo que permita colocar um pequeno texto sobre a proximidade de algum local conhecido. Prever além dos métodos de acesso aos atributos, um método que permita receber como parâmetro uma palavra chave a ser procurada neste texto. Este método deve retornar um booleano indicando se a palavra chave existe no texto.
  5. Implemente uma classe que representa bandas de rock. Preveja um atributo que permita representar as canções e discos da banda. Pense na possibilidade de que destes atributos também sejam classes.

AULA 10 - Dia 03/05/2019

OBJETIVOS

  • strings em C++ (ver material Prof.Sobral)
    • Lendo ou escrevendo strings em streams
    • Conversão de string para tipos numéricos
  • streams e arquivos


Exercício em sala - organização dos arquivos

main.h

#ifndef MAIN_H
#define MAIN_H

#include "triangulo.h"

extern Triangulo y;

#endif

main.cc

#include "main.h"
#include "triangulo.h"

using namespace std;


Triangulo y(1.5,10.7,9.0);


main()
{
  Triangulo *p;
  Triangulo x(10.0,9.5,4.7);

  p = new Triangulo(1.5, 2.7,9.9);


  p->printTriangulo();
  x.printTriangulo();
  y.printTriangulo();
  (*p).printTriangulo();
}

triangulo.h

#ifndef TRIANGULO_H
#define TRIANGULO_H

class Triangulo {
private:
  float lado1, 
        lado2,
        lado3;
public:
  Triangulo(float l1, float l2, float l3) {
     lado1 = l1;
     lado2 = l2;
     lado3 = l3;
  }
  void printTriangulo();
}; 


#endif

triangulo.cc

#include "triangulo.h"
#include <iostream>

using namespace std;



void Triangulo::printTriangulo()
{
  cout << "Alo - sou o triangulo" << "\n";
}

AULA 11 - Dia 10/05/2019

OBJETIVOS

  • Associações entre classes;
  • Agregação X Composição

Link Aulda do Prof.Emerson

Associação

Uma relação entre duas classes onde uma delas se utiliza dos "serviços" da outra (associação unidirecional) ou ambas se utilizam (associação bidirecional). O tempo de vida dos objetos instanciados a partir destas classes são independentes: se um objeto for destruído o outro pode continuar a existir.

Normalmente, o objeto que usar um serviço de outro objeto associado, terá um ponteiro para este objeto.

Exemplo: Uma pessoa pode possuir livros. Se a pessoa "morre" os livros continuam a existir. Se um livro é perdido ou destruído a pessoa continua a existir. Em termos de implementação em C++ a classe que usa o serviço da outra classe associada deve possuir um ponteiro para a outra classe.

#include  <queue>
#include  <iostream>
#include  <string>

using namespace std;

class Livro{
 private:
   string Titulo;
 public:
   Livro(string tit): Titulo(tit){};
   string getTitulo() { return Titulo;};
};

class Pessoa{
 private:
  string meuNome;
  vector <Livro *> meusLivros;
 public:
  Pessoa(string nome): meuNome(nome){};
  ~Pessoa(){ cout << "Eu, " << meuNome << " fui..." << '\n';}
  void addLivro(Livro *liv);
  void printLivros();
};

void Pessoa::addLivro(Livro *liv)
{
  meusLivros.push_back(liv);
}

void Pessoa::printLivros()
{
  for (int i = 0; i != meusLivros.size(); i++)
      cout <<  meusLivros[i]->getTitulo() << '\n';
}

main()
{
  Livro l1("E o Vento Levou"), l2("O Guarani");
  Pessoa *p1 = new Pessoa("Fulana");

  p1->addLivro(&l1);  
  p1->addLivro(&l2);

  p1->printLivros();
  
  delete p1; // pessoa morreu ...
  
  cout << "Os livros " << l1.getTitulo() << " e " << l2.getTitulo() << " ainda continuam a existir\n";
}

Exercício: Uma estante de uma biblioteca contém livros. Seria esta uma associação simples? Crie classes de forma similar ao exemplo anterior para representar esta situação. Coloque métodos de forma similar ao exemplo anterior e teste na função main. ACRESCENTAR um método para retirar livro da estante.

OBSERVAÇÃO: para remover dados do vetor:

Exemplo de um código para remover um item do vetor:

#include  <queue>
#include  <iostream>
#include  <string>
 
using namespace std;
 
class Livro{
 private:
   string Titulo;
 public:
   Livro(string tit): Titulo(tit){};
   string getTitulo() { return Titulo;};
};
 
class Pessoa{
 private:
  string meuNome;
  vector <Livro *> meusLivros;
 public:
  Pessoa(string nome): meuNome(nome){};
  ~Pessoa(){ cout << "Eu, " << meuNome << " fui..." << '\n';}
  void addLivro(Livro *liv);
  void removeLivro(string nome);
  void printLivros();
};
 
void Pessoa::addLivro(Livro *liv)
{
  meusLivros.push_back(liv);
}
 
void Pessoa::printLivros()
{
  for (int i = 0; i != meusLivros.size(); i++)
      cout <<  meusLivros[i]->getTitulo() << '\n';
}
 
void Pessoa::removeLivro(string nome)
{
  bool encontrado = false;

  for (int i = 0; i != meusLivros.size() & encontrado==false; i++) {
      if (nome== meusLivros[i]->getTitulo()) {
          encontrado = true;
          meusLivros.erase(meusLivros.begin()+i);
      }
  }
}

main()
{
  Livro l1("E o Vento Levou"), 
        l2("O Guarani"),
        l3("O Continente");
  Pessoa *p1 = new Pessoa("Fulana");
 
  p1->addLivro(&l1);  
  p1->addLivro(&l2);
  p1->addLivro(&l3); 
  p1->printLivros();

  cout << "removendo um item ,,,\n";

  p1->removeLivro("O Guarani");
  p1->printLivros(); 

  delete p1; // pessoa morreu ...
 
  cout << "Os livros " << l1.getTitulo() << " e " << l2.getTitulo() << " ainda continuam a existir\n";
}

Composição

Existem situações em que existe uma forte associação entre classes e em que o tempo de vida delas coincidem ou possuem uma estreita relação. Pode-se dizer que as classes dos objetos relacionados pertencem a classe do objeto. Nesta relação existe uma relação de propriedade onde uma classe(objeto) POSSUI outras classes(objetos).

Exemplo: Livros contém capítulos. Não é possível que os capítulos sobrevivam ao livro (pelo menos em condições normais):

#include  <queue>
#include  <iostream>
#include  <string>

using namespace std;

class Capitulo{
  private:
   string Titulo;
  public:
   Capitulo(string tit): Titulo(tit){};
   ~Capitulo(){ cout << "Capitulo " << Titulo << " destruido\n";};
   string getTitulo() { return Titulo;}; 
};

class Livro{
 private:
   string Titulo;
   vector <Capitulo *> Capitulos;
 public:
   Livro(string tit): Titulo(tit){};
   ~Livro();

   void addCapitulo (Capitulo *cap);
   string getTitulo() { return Titulo;};
};

void Livro::addCapitulo(Capitulo *cap)
{
  Capitulos.push_back(cap);
}

Livro::~Livro()
{
  for (int i = 0; i != Capitulos.size(); i++) {
     delete Capitulos[i];
  }
}

main()
{
  Livro *l1 = new Livro("O Tempo e o VEnbto");
  
  l1->addCapitulo (new Capitulo("cap1"));
  l1->addCapitulo (new Capitulo("cap2"));

  
  delete l1; // lvro destruido
  
}

Ver https://www.toptal.com/c-plus-plus/top-10-common-c-plus-plus-developer-mistakes

Referências interessantes:

https://www.learncpp.com/cpp-tutorial/103-aggregation/ https://scs.senecac.on.ca/~oop345/pages/content/compo.html

AULA 12 - Dia 17/05/2019

OBJETIVOS

  • Ainda associações: agregação
  • Herança
  • Polimorfismo e Funções Virtuais

Texto Indicado

https://www.ibm.com/developerworks/br/rational/library/content/RationalEdge/sep04/bell/index.html

https://www.learncpp.com/cpp-tutorial/103-aggregation/

Ainda associações: agregação

A agregação é uma relação parte-todo similar a composição vista na aula anterior. Entretanto, a classe (objeto) parte não tem a sua vida controlada pela classe que representa o todo.

Exemplo 1: Carro Roda Peças

Pode-se dizer que a roda faz parte do carro: o TODO (carro) contém 4 rodas (classe membro). Mas pode-se imaginar que a roda pode ser substituída por outra. Observe que neste exemplo existe uma relação de multiplicidade 1 carro para 4 rodas.

Exemplo 2: Professor Departamento

Um professor PERTENCE a um Departamento. Por exemplo um objeto que representa o Prof.Fulano pertence ao objeto Departamento de Telecomunicações. Entretanto, eventualmente este professor pode mudar de departamento ou mesmo se aposentar e deixar de fazer parte deste departamento. Se o departamento for extinto o professor continua sendo professor.

Exemplo 3: Comissão - Membros da Comissão

Será que trata-se de uma AGREGAÇÂO?

A comissão (todo) possui membros (pessoas). Uma comissão pode ter 0 ou mais membros (temporariamente uma comissão poderia estar completamente desfalcada...). NOTE que esta relação pode ser considerada MAIS forte e poderia ser vista como uma COMPOSIÇÃO. Os membros da comissão deixariam de existir enquanto membros caso a comissão seja extinta por exemplo.


Herança

Em OO e no C++ é possível criar classes (CLASSES DERIVADAS OU SUBCLASSE) tendo como base outra classe (CLASSE BASE ou SUPERCLASSE) de forma a usufruir das características desta classe. Este processo de construir classes a partir de outras classes chama-se HERANÇA e a classe DERIVADA é uma ESPECIALIZAÇÃO da classe BASE.

Note que o processo de ESPECIALIZAÇÃO permite REUTILIZAR CÓDIGO já desenvolvido.

Exemplo 1: Professor, Aluno, Pessoa

No exemplo abaixo é criado uma classe Professor DERIVADA da classe BASE Pessoa. Trata-se de uma ESPECIALIZAÇÃO onde pode-se usufruir dos métodos PÚBLICOS da classe BASE (desde que se informe a palavra chave public).

#include  <queue>
#include  <iostream>
#include  <string>
 
using namespace std;
 
class Pessoa {
 private:
  string Nome; 
 public:
  Pessoa(string meuNome){ 
        Nome=meuNome; 
        cout << "Construtor da classe pessoa\n"; 
        };
  string getNome (){return Nome;};
};
 
class Professor: public Pessoa{
 private:
   string Especialidade;
 public:
   Professor(string meuNome, string minhaEspecialidade): Especialidade(minhaEspecialidade), Pessoa(meuNome)
   {
      cout << "Construtor da classe Professor\n"; 
   };
   string getEspecialidade(){return Especialidade;};  
};

 
main()
{
  Professor Prof1("Joao", "telecom");
  Professor *Prof2 = new Professor("Maria", "ingles");
 
  cout << "Meu nome é " <<  Prof1.getNome() << " e minha especialidade é " << Prof1.getEspecialidade()  << "\n";
  cout << "Meu nome é " <<  Prof2->getNome() << " e minha especialidade é " << Prof2->getEspecialidade()  << "\n";
 
  delete Prof2;
}

EXERCÍCIO: Acrescentar uma classe Aluno DERIVADA da classe BASE Pessoal. O aluno deve possuir um número de matrícula. Crie dois alunos e imprima o nome e a matrícula destes alunos.

Exemplo 2: GerenteProjeto, Programador, Empregado, Pessoa

#include  <queue>
#include  <iostream>
#include  <string>
 
using namespace std;
 
class Pessoa {
 private:
  string Nome; 
 public:
  Pessoa(string meuNome){ Nome=meuNome;};
  string getNome (){return Nome;};
};

class Empregado: public Pessoa{
 private:
   float salario;
   int numInscricao;
 public:
   Empregado(string meuNome, float meuSalario, int  minhaInscricao): Pessoa(meuNome), salario(meuSalario), numInscricao(minhaInscricao){};
   float getSalario(){return salario;};  
};


class Programador: public Empregado{
  private:
    string Linguagem;
  public:
    Programador(string meuNome, string minhaLinguagem, float meuSalario, int minhaInscricao):
    Linguagem(minhaLinguagem), Empregado(meuNome, meuSalario, minhaInscricao) {};
    string getLinguagem(){return Linguagem;};
};

main()
{
  Programador prog1("Joao", "C++", 5000.00, 12345);
  cout << "Meu nome é " << prog1.getNome() << " e minha linguagem é " << prog1.getLinguagem() << " e meu salario é " << prog1.getSalario() << "\n";
}

ATENÇÂO SOBRE A ORDEM DE CHAMADA DE CONSTRUTORES E DESTRUTORES

Execute com o professor os exemplos do link: [3]

Atividade POO-C++ 2

  1. No exemplo do Programador/Empregado/Pessoa, adicione as seguintes características:
    1. Um Diretor (onde se possa atribuir o nome do Departamento (uma string))
    2. Um Motorista (onde se pode atribuir uma lista de carros que sabe dirigir (ver exercícios da aula passada);
  2. No exercício anterior criar uma classe que permita identificar o endereço dos empregados.
  3. No exercício anterior criar uma classe que permita representar a empresa e departamento onde trabalham os funcionários. Esta empresa possui 2 departamentos cada departamento com um programador um diretor.
  4. No exercício anterior crie a noção de projeto. O projeto pode conter quaisquer funcionários da empresa. Crie dois projetos com 3 funcionários. Crie facilidades para imprimir integrantes dos projetos.

AULA 13 - Dia 23/05/2019

OBJETIVOS

  • ainda herança
  • classes abstratas e funções virtuais

Classes Abstratas e Funções virtuais

Uma classe abstrata possui métodos que não estão implementados. Ela serve como base para classes derivadas que deverão implementar estes métodos. No C++ uma classe abstrata é definida quando ser cria um método virtual da forma:

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

// a classe veículo não sabe acelerar...Depende do veículo... 
class Veiculo
{
protected:
   float velocidade;
   string dono;
public:
   Veiculo(string meuDono){dono = meuDono; velocidade=0;}
   virtual void acelerar () = 0;
};

class Carro: public Veiculo{
public:
  Carro (string dono): Veiculo(dono) {}
  void acelerar() { 
    velocidade = velocidade + 0.1;
    cout << "acelerou para " << velocidade << "\n";
  }
};

main()
{
 Carro carro1("Joao");
 
 carro1.acelerar();
}

Ver comentários sobre classes abstratas em C++ aqui [4]

NOTAR que não é possível criar um objeto da classe abstrata. Mas nada impede que um ponteiro seja criado...

EXERCÌCIOS

  1. Refaça o exemplo anterior tentando instanciar MeuCarro a partir da classe Veiculo. Compile e analise o erro.
  2. Refaça o exemplo anterior criando uma classe Navio e implemente uma aceleração diferenciada...
  3. Em um programa principal crie um vetor de ponteiros para Veiculo. Coloque na fila alguns carros e alguns navios. Faça um código para acelerar todos os veículos da tabela.
#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

// a classe veículo não sabe acelerar...Depende do veículo... 
class Veiculo
{
protected:
   float velocidade;
   string dono;
public:
   Veiculo(string meuDono){dono = meuDono; velocidade=0;}
   virtual void acelerar () = 0;
};

class Carro: public Veiculo{
public:
  Carro (string dono): Veiculo(dono) {}
  void acelerar() { 
    velocidade = velocidade + 0.1;
    cout << "acelerou para " << velocidade << "\n";
  }
};

class Navio: public Veiculo{
public:
  Navio (string dono): Veiculo(dono) {}
  void acelerar() { 
    velocidade = velocidade + 0.1;
    cout << "acelerou para " << velocidade << "\n";
  }
};

main()
{
 vector <Veiculo *> tabelaVeiculos;
 
 tabelaVeiculos.push_back(new Carro("Joao"));
 tabelaVeiculos.push_back(new Navio("Maria"));
 tabelaVeiculos.push_back(new Carro("Josefina"));
}

EXERCÍCIO ADICIONAL

  1. Em um sistema de controle de acesso temos objetos "portas" criados a partir de classes derivadas de uma classe base "class porta". Esta classe é abstrata pois tem um método abrirPorta() puramente virtual. As classes derivadas são "class portaSanfonada", "class portaNormal" e "class portaCorrer". Construa uma tabela global contendo 10 portas de diferentes tipos e uma função que permite em caso de emergência abrir todas as portas que estão na tabela.

AULA 14 - Dia 30/05/2019

OBJETIVOS

  • Criação de Objetos;
    • objetos globais;
    • objetos locais;
    • objetos criados dinamicamente;

Criação de Objetos

Criação de Objetos Globais

Objetos podem ser criados globalmente o que permite uma visibilidade por todos os demais objetos. Objetos globais são criados logo que o programa é executado e deixam de existir no encerramento do mesmo. Portanto, o TEMPO DE VIDA do objeto é o tempo de vida do programa em execução. Observe o exemplo abaixo:

#include <iostream>

extern int main();

using namespace std;

class personagemStarTrek{
 private:
    string nome;
 public:
    personagemStarTrek(string meuNome) : nome(meuNome) { cout<< nome << ": objeto criado... " << endl;}
    ~personagemStarTrek(){ cout<< nome << ": objeto destruído.." << endl;}
} o1("Spock"), o2("Uhura");;

int main()
{
  cout <<"main()\n";
}

Ao executar este programa vamos obter a seguinte saída:

Spock: objeto criado... Uhura: objeto criado... main() Uhura: objeto destruído.. Spock: objeto destruído.. </syntaxhighlight>

Podemos concluir que os objetos o1 e o2, (através de seus construtores) foram criados ANTES mesmo da função "main()" ser invocada. O destrutor do objeto foi chamado APÓS o final do "main()".

Note que um objeto global pode potencialmente ser visto por todos os demais objetos do programa. Entretanto, ao organizar o código em arquivos separados no cabeçalho (arquivo .h) deve-se declarar:

extern class personagemStarTrek o1, o2;

Desta forma outros objetos poderão referenciar estes objetos.

Uma QUESTÃO conceitual é DEVO ou é RECOMENDADO usar objetos globais? Em programação orientada a objetos pode ser fonte de aumento de coesão entre objetos e em GERAL deve-se evitar o uso (pelo menos em grandes programas).

Criação Local de Objetos e Limitação do Escopo

Quando se declara um objeto dentro de um bloco { }</syntaxhighlight> estamos limitando o TEMPO DE VIDA e a visibilidade (escopo) do objeto ao bloco. Vamos a mais um exemplo:

#include <iostream>

extern int main();

using namespace std;

class personagemStarTrek{
 private:
    string nome;
 public:
    personagemStarTrek(string meuNome) : nome(meuNome) { cout<< nome << ": objeto criado... " << endl;}
    ~personagemStarTrek(){ cout<< nome << ": objeto destruído.." << endl;}
};

int main()
{  //bloco 1
   personagemStarTrek o1("Spock"); 
   {   //bloco 2
       personagemStarTrek o2("Uhura");
       {  // bloco 3
          personagemStarTrek o2("Kirk");
       }
   }
}


Observe a saída deste programa: Spock: objeto criado... Uhura: objeto criado... Kirk: objeto criado... Kirk: objeto destruído.. Uhura: objeto destruído.. Spock: objeto destruído.. </syntaxhighlight>

Observe que o objeto "o1" foi criado no "bloco 1'. Ele deixa de existir quando o bloco se encerra. Note que foram criados dois objetos de nome o2 (("variable shadowing")). O primeiro no bloco 2 e o segundo no bloco 3. Não existe problema nenhum (a não ser conceitual) e a existência dos objetos é restrita ao bloco .

NOTE que o uso de objetos com mesmo nome torna o código CONFUSO. Escolher nome significativos e que não levem a interpretação dúbia em termos de ESCOPO é uma prática.

Criação Dinâmica de Objetos

A qualquer momento pode-se criar dinamicamente um objeto usando o operador "new". Entretanto, alguns pontos devem ser observados:

  • quando o objeto não for mais utilizado, ele deve ser "destruído" com o operador "delete". Por que? Estes objetos são criados em uma área de memória específica (HEAP). Suponha que um código se execute, por exemplo, durante um ano inteiro. Criando objetos sem destruí-los, chegará um momento em que esta área não terá mais espaço para acomodar novos objetos... É o momento de um possível PANIC no software.
  • sempre devemos ter um apontador para este objeto pois caso, por algum motivo, perdemos este apontador, não será possível deletar o objeto.

Vamos ao exemplo:

#include <iostream>

extern int main();

using namespace std;

class personagemStarTrek{
 private:
    string nome;
 public:
    personagemStarTrek(string meuNome) : nome(meuNome) {
            cout<< nome << ": objeto criado antes... " << endl;
            }
    ~personagemStarTrek(){ cout<< nome << ": objeto destruído.." << endl;}
    string getNome(){ return nome;}
};

int main()
{
   personagemStarTrek *p1=  new personagemStarTrek("Dr.Spock");

   delete p1;
}

Mais sobre uso destes operadores aqui [5]

Ponteiros versus Referências

#include <iostream>

struct teste {
  private:
   int x;
  public:
   teste(){ x = 2; }
   int getx(){return x;}
};

main()
{
 teste alfa;
 teste *p = &alfa;
 teste &beta = alfa;

 std::cout << "valor de x em alfa " << alfa.getx() << std::endl;
 std::cout << "valor de x via ponteiro p " << p->getx() << std::endl;
 std::cout << "valor de x via beta " << beta.getx() << std::endl;

 std::cout << "endereço de alfa " << &alfa << std::endl;
 std::cout << "endereço de p " << &p << std::endl;
 std::cout << "conteúdo de p " << p << std::endl;
 std::cout << "endereço de beta " << &beta << std::endl;
}

Uma possível saída (depende da sua máquina):

valor de x em alfa 2 valor de x via ponteiro p 2 valor de x via beta 2 endereço de alfa 0x7ffe22fa4ad0 endereço de p 0x7ffe22fa4ae0 conteúdo de p 0x7ffe22fa4ad0 endereço de beta0x7ffe22fa4ad0 </syntaxhighlight>

#include <iostream>

struct teste {
  private:
   int x;
  public:
   teste(){ x = 2; }
   int getx(){return x;}
};

void funcao_teste(teste &y)
{
 std::cout << "endereço de y " << &y << std::endl;
 std::cout << "acessando x em y " << y.getx() << std::endl;
}

main()
{
 teste alfa;
 teste &beta = alfa;

 std::cout << "endereço de alfa " << &alfa << std::endl;
 funcao_teste(alfa);
}

Possível saída: endereço de alfa 0x7fff0c909420 endereço de y 0x7fff0c909420 acessando x em y 2 </syntaxhighlight>

Cópia de objetos no retorno da Função

Observe o exemplo abaixo:

#include <iostream>
 
extern int main();
 
using namespace std;
 
class personagemStarTrek{
 private:
    string nome;
 public:
    personagemStarTrek(string meuNome) : nome(meuNome) {
            cout<< nome << ": objeto criado..." << endl;
            }
    ~personagemStarTrek(){ cout<< nome << ": objeto destruído.." << endl;}
    string getNome(){ return nome;}
};
 
personagemStarTrek alfa()
{
  personagemStarTrek x("McCoy");
  return x;
}

int main()
{
   personagemStarTrek a("Chekov");
 
   a=alfa();
}

A saída deve ser: Chekov: objeto criado... McCoy: objeto criado... McCoy: objeto destruído.. McCoy: objeto destruído.. </syntaxhighlight> Inicialmente o objeto "a" (Chekov) é criado. A função "alfa()" é então chamada. A variável local x é criada (McCoy). No retorno o valor de x é retornado, o objeto em si destruído e o valor copiado para a. No final "a" é destruído.

O ponteiro predefinido this

Ver material do Professor Sobral

Construtor de cópia

Ver material do Professor Sobral

AULA 15 - Dia 07/06/2019

Objetivos

  • Arrays no C++
  • Vectors da STL no C++

Arrays no C++ - Formato tradicional

Uma forma simples de organizar os dados em um formato de uma "tabela" que pode indexada no C/C++ é através dos arrays. No C/C++ pode-se por exemplo definir um array de inteiros da forma:

#include <iostream>

main()
{
 int x[10] = {2,5,3,8,1,3,4,5,9,10}; 
 int i;
 
 for (i=0;i<10;i++)
    cout "valor de x na posição " << i << " é " << x[i] << eol; 
}

Com a saída:

valor de x na posição 0 é 2 valor de x na posição 1 é 5 valor de x na posição 2 é 3 valor de x na posição 3 é 8 valor de x na posição 4 é 1 valor de x na posição 5 é 3 valor de x na posição 6 é 4 valor de x na posição 7 é 5 valor de x na posição 8 é 9 valor de x na posição 9 é 10 </syntaxhighlight>

Array de Objetos e de Ponteiros para Objetos

È possível usar o mesmo mecanismo para construir arrays de objetos:

(ver [6])

#include <iostream>
#include <cstring>

using namespace std;

class Pessoa {
  private:
   string nome;
   int idade;
  public:
   Pessoa(string meuNome, int minhaIdade) { nome = meuNome; idade = minhaIdade; }; 
   string getNome(){return nome;}
};

int main()
{
 Pessoa x[3] = {Pessoa("Joao",21), Pessoa("Maria",19), Pessoa("Pedro",19)}; 
 int i;
 
 for (i=0;i<3;i++)
    cout << "nome no objeto  da posição " << i << " do vetor x é " << x[i].getNome() << endl; 
}

Com a saída: nome no objeto da posição 0 do vetor x é Joao nome no objeto da posição 1 do vetor x é Maria nome no objeto da posição 2 do vetor x é Pedro </syntaxhighlight>

Pode-se definir um array de ponteiros para objetos:

#include <iostream>
#include <cstring>


using namespace std;

class Pessoa {
  private:
   string nome;
   int idade;
  public:
   Pessoa(string meuNome, int minhaIdade) { nome = meuNome; idade = minhaIdade; }; 
   string getNome(){return nome;}
};

int main()
{
 Pessoa* x[3] = {NULL, NULL, NULL}; 
 int i;
 

 x[0] =  new Pessoa("Joao",21);
 x[1] =  new Pessoa("Maria",19);
 x[2] =  new Pessoa("Pedro",19);
 
 for (i=0;i<3;i++) 
    cout << "nome no objeto  da posição " << i << " do vetor x é " << x[i]->getNome() << endl; 

 for (i=0;i<3;i++) 
    delete x[i];
}

A saída é similar a anterior.

Deve ser observado que deve-se "gerenciar" a inserção, remoção e edição de itens do array. Pode-se por exemplo definir uma classe que contém um array e nesta classe fornecer métodos para adicionar ou remover itens. Exemplo:


#include <iostream>
#include <cstring>


using namespace std;

class Pessoa {
  private:
   string nome;
   int idade;
  public:
   Pessoa(string meuNome, int minhaIdade) { nome = meuNome; idade = minhaIdade; }; 
   string getNome(){return nome;}
};


class ListaPessoas {
  private:
    Pessoa* lista[3];
  public:
    ListaPessoas () { int i; for (i=0;i<3;i++) lista[i] = NULL;}
    ~ListaPessoas ()
    {
      for (int i=0;i<3;i++) 
        delete lista[i];
    }
    int addPessoa(Pessoa *p) 
    { 
      int i; 
      for (i=0;i<3;i++) { 
         if (lista[i] == NULL) // encontrar local de inserção
             break;
      }
      if (i==3)
          return -1;
      else {
          lista[i] = p;
          return i;
      }
    }
    void printPessoas()
    { 
      for (int i=0;i<3;i++) 
          cout << "nome no objeto  da posição " << i << " do vetor x é " << lista[i]->getNome() << endl; 
    }

};
 
int main()
{
 Pessoa* x[3] = {NULL, NULL, NULL}; 
 ListaPessoas Contatos;
 int i;
 

 Contatos.addPessoa ( new Pessoa("Joao",21) );
 Contatos.addPessoa ( new Pessoa("Maria",19) );
 Contatos.addPessoa ( new Pessoa("Pedro",19) );
 
 Contatos.printPessoas();
}

Uso da biblioteca stl (uso de vectors)

O C++ possui a biblioteca stl que fornece containers para armazenamento. Existe uma série de métodos já implementados que facilitam a inserção, remoção e ordenamento de itens em vetores e listas. Já exploramos o vector em exemplos anteriores. Nosso exemplo ficaria da forma:

#include <queue>
#include <iostream>
#include <cstring>


using namespace std;

class Pessoa {
  private:
   string nome;
   int idade;
  public:
   Pessoa(string meuNome, int minhaIdade) { nome = meuNome; idade = minhaIdade; }; 
   string getNome(){return nome;}
};

class ListaPessoas {
  private:
    vector <Pessoa *> lista;
  public:
    ListaPessoas () {}
    ~ListaPessoas ()
    {
      for (int i=0;i<lista.size();i++) 
        delete lista[i];
    }
    int addPessoa(Pessoa *p) 
    { 
       lista.push_back(p);
    }
    void printPessoas()
    { 
      for (int i=0;i<lista.size();i++) 
          cout << "nome no objeto  da posição " << i << " do vetor lista é " << lista[i]->getNome() << endl; 
    }

};
 
int main()
{
 Pessoa* x[3] = {NULL, NULL, NULL}; 
 ListaPessoas Contatos;
 int i;
 

 Contatos.addPessoa ( new Pessoa("Pedro",19) );
 Contatos.addPessoa ( new Pessoa("Joao",21) );
 Contatos.addPessoa ( new Pessoa("Maria",19) );
 
 Contatos.printPessoas();
}

Observe que o vetor cresce dinamicamente quando um item é "empurrado" para o mesmo. Note que o vetor não está ordenado. É possível ordenar o vetor usando o método sort do stl. Deve-se fornecer, no entanto, uma função de ordenamento:

#include <queue>
#include <iostream>
#include <cstring>
#include<bits/stdc++.h>

using namespace std;

class Pessoa {
  private:
   string nome;
   int idade;
  public:
   Pessoa(string meuNome, int minhaIdade) { nome = meuNome; idade = minhaIdade; }; 
   string getNome(){return nome;}
};

bool compararPessoa(Pessoa* i1, Pessoa* i2) 
{ 
  return ((i1->getNome()).compare(i2->getNome()) < 0); 
} 

class ListaPessoas {
  private:
    vector <Pessoa *> lista;

  public:
    ListaPessoas () {}
    ~ListaPessoas ()
    {
      for (int i=0;i<lista.size();i++) 
        delete lista[i];
    }
    int addPessoa(Pessoa *p) 
    { 
       lista.push_back(p);
    }
    void printPessoas()
    { 
      for (int i=0;i<lista.size();i++) 
          cout << "nome no objeto  da posição " << i << " do vetor lista é " << lista[i]->getNome() << endl; 
    }
    void sortLista()
    {
       sort(lista.begin(),lista.end(), compararPessoa);  
    }
  
};
 
int main()
{
 Pessoa* x[3] = {NULL, NULL, NULL}; 
 ListaPessoas Contatos;
 int i;
 
 Contatos.printPessoas();

 Contatos.addPessoa ( new Pessoa("Pedro",19) );
 Contatos.addPessoa ( new Pessoa("Joao",21) );
 Contatos.addPessoa ( new Pessoa("Maria",19) );
  
 Contatos.sortLista();

 Contatos.printPessoas();
}

Para procurar itens em uma lista existem várias opções interessantes na biblioteca stl. Entretanto, uma forma convencional de acesso é mostrada abaixo.

#include <queue>
#include <iostream>
#include <cstring>
 
 
using namespace std;
 
class Pessoa {
  private:
   string nome;
   string senha;
   int idade;
  public:
   Pessoa(string meuNome, string minhaSenha, int minhaIdade) { nome = meuNome; senha = minhaSenha; idade = minhaIdade; }; 
   string getNome(){return nome;}
   string getSenha(){return senha;}
};
 
class ListaPessoas {
  private:
    vector <Pessoa *> lista;
  public:
    ListaPessoas () {}
    ~ListaPessoas ()
    {
      for (int i=0;i<lista.size();i++) 
        delete lista[i];
    }
    int addPessoa(Pessoa *p) 
    { 
       lista.push_back(p);
    }
    Pessoa* findPessoaPorSenha(string senha) {
      bool flag=false;
      int i;
      for (i=0;i<lista.size();i++){
          if (senha == lista[i]->getSenha()) {
             flag=true;
             break;
          }
      }
      if (flag==true)
            return lista[i];
      else 
            return NULL;
    }

    void printPessoas()
    { 
      for (int i=0;i<lista.size();i++) 
          cout << "nome no objeto  da posição " << i << " do vetor lista é " << lista[i]->getNome() << endl; 
    }
 
};
 
int main()
{
 Pessoa* x[3] = {NULL, NULL, NULL}; 
 ListaPessoas Contatos;
 int i;
 
 
 Contatos.addPessoa ( new Pessoa("Pedro","abcd",19) );
 Contatos.addPessoa ( new Pessoa("Joao","jklm",21) );
 Contatos.addPessoa ( new Pessoa("Maria","mnop",19) );
 
 Contatos.printPessoas();

 cout << "Pessoa com senha abcd é " << Contatos.findPessoaPorSenha("abcd")->getNome() << endl; 
}

AULA 16 - Dia 8/06/2019 (projeto - Aula a sábado)

Objetivos

  • Sprint 4 (FASE 4) do Projeto
  • Implementação de casos de uso abrir porta

Relato das Atividades

  • Seleção de um caso de uso para ser implementado: Abrir Porta
  • Discussão do Diagrama de Sequência
  • Implementação do Esqueleto das Classes (.h e .cpp)

Diagrama De Sequência Discutido

DiagramaSequenciaAbrirPorta.png

AULA 17 - Dia 14/06/2019 (projeto - Aula a sábado)

Objetivos

  • Sprint 5 (FASE 5) do Projeto - Foco: caso de uso Gerenciar Usuários
  • Implementação do Gerenciamento de Usuários
    • Melhoria das classes associadas aos usuários
    • Edição de usuários: inserção/remocão de usuários na lista.

Uma classe de associação usando multimap do STL

using namespace std;
 
class SalaUsuarios{
  private:
   multimap <string, string> TabSalaUsuarios;
  public:
   SalaUsuarios();
   void printSalasUsuarios();
   bool isInSala(string sala, string nome);
};

SalaUsuarios::SalaUsuarios()
{
  TabSalaUsuarios.insert(pair <string, string> ("salaCad1", "joaoId"));
  TabSalaUsuarios.insert(pair <string, string> ("salaCad1", "laraId"));
  TabSalaUsuarios.insert(pair <string, string> ("salaRedes", "laraId"));
  TabSalaUsuarios.insert(pair <string, string> ("salaRedes", "mariaId"));
}

void SalaUsuarios::printSalasUsuarios()
{
  multimap <string, string> :: iterator itr; //Declaração do iterator (uma espécie de ponteiro para o container
  for (itr = TabSalaUsuarios.begin(); itr != TabSalaUsuarios.end(); ++itr) 
  { 
        std::cout  <<  '\t' << itr->first <<  '\t' << itr->second << '\n'; 
  } 
}

bool SalaUsuarios::isInSala(string sala, string nome)
{
  multimap <string, string> :: iterator itr; //Declaração do iterator (uma espécie de ponteiro para o container
  for (itr = TabSalaUsuarios.find(sala); itr != TabSalaUsuarios.end(); itr++) {
     if (itr->second == nome) {
        return true;
     }
  }
  return false;
}

main()
{
  SalaUsuarios TabSalaUsuarios;
  
  TabSalaUsuarios.printSalasUsuarios();

  std::cout << TabSalaUsuarios.isInSala("salaCad1","laraId") << endl ;
  std::cout << TabSalaUsuarios.isInSala("salaRedes","laraId") << endl ;
}

AULA 17 - Dia 6/06/2019 (projeto - Aula a noite)

AULA 18 - Dia 7/06/2019

OBJETIVOS

  • Acesso a banco de dados usando o C++

AULA 19 - Dia 13/06/2019 (projeto - Aula a noite)

AULA 20 - Dia 14/06/2019

OBJETIVOS

AULA 21 - Dia 18/06/2019 (por causa do feriado)

AULA 22 - Dia 19/06/2019 (projeto - Aula a noite)

AULA 23 - Dia 20/06/2019 (projeto - Aula a noite)

OBJETIVOS

AULA 24 - Dia 26/06/2019 (projeto aula a noite)

Previsão de 3ha

AULA 25 - Dia 27/06/2019 (projeto aula a noite)

Previsão de 3ha

AULA 26 - Dia 28/06/2019

  • Apresentação do Projeto Final

OBJETIVOS

AULA 27 - Dia 5/07/2019

  • Recuperação da A1

OBJETIVOS

AULA 28 - Dia 9/07/2019

  • Reapresentação do Projeto