Recibo da Frequência de Programação Orientada para Objectos (IGE e ETI), 2º semestre de 2000/2001, ISCTE:
Nome do aluno: _______________________________________________
Número do aluno: ______________________
Assinatura do docente: ________________________________________
Identificação
Nome do aluno: _______________________________________________
Número do aluno: ______________________
Turma: ____________
Frequência
Programação Orientada para Objectos
IGE e ETI
2º semestre de 2000/2001
ISCTE
Deve preencher todos os espaços indicados por um sublinhado (___) com V ou F. Qualquer espaço não preenchido será considerado como uma resposta errada.
Em geral as alíneas podem ter zero ou mais respostas correctas. Cada resposta correctamente assinalada vale 0,5 valores.
Nas alíneas em que apenas uma resposta está correcta (se existirem estão assinaladas no texto), responder com mais ou menos do que um V anula a cotação. A resposta correcta corresponde à cotação completa. Qualquer outra resposta corresponde a zero valores.
Considere as seguintes classes:
class B {
public:
B();
virtual ~B();
virtual void m1() = 0;
};
class DdeB : public B {
public:
DdeB();
virtual void m1();
virtual void m2(int p);
};
class DdeD: public DdeB {
public:
DdeD();
virtual void m2(int p);
};
1.1 Quais das seguintes instruções estão correctas?
__ B* b = new
DdeB(); b->m1();
__ B* b = new B(); b->m1();
__ B* b = new DdeD(); b->m2(3);
1.2 Quais das seguintes definições estão correctas?
__ void DdeD() { cout << "DdeD::DdeD()" <<
endl; }
__ DdeD() : DdeB(), B() {}
__ DdeD() : DdeB() {}
[cotação: 1,5]
1.3 Dado o seguinte código:
double a = 3.0;
int* b = 0;
float c = 3.14;
int const* d = new int[4];
int* const e = new int[5];
Quais das seguintes instruções estão correctas?
__ int* resultado = a < 3.5 ? a : 3.5;
__ b = &c;
__ ++d;
__ ++e;
[cotação: 2]
Questão 2
Recorde-se que deve ler atentamente todo o enunciado antes de resolver as questões!
Pretende-se implementar, em C++, uma aplicação para apoio à divulgação de notícias. Esta aplicação permite aos seus utilizadores consultar e registar notícias. São mostradas todas as notícias que se encontram na lista gerida por esta aplicação sempre que um utilizador assim o peça.
A aplicação responsabiliza-se pela actualização das notícias disponíveis para consulta, analisando diariamente as condições necessárias à disponibilização de notícias: as notícias que não verifiquem as condições são removidas da lista gerida por esta aplicação.
A definição da classe GestorDeNotícias, seguidamente
apresentada, é uma simplificação da classe que gere as notícias na referida
aplicação:
class GestorDeNotícias {Método invocado diariamente para actualizar as notícias:
public:
GestorDeNotícias();
~GestorDeNotícias();
//O parâmetro
void actualiza(Data const& data_actual);
void registaNotícia(Notícia* notícia);
void cancelaAcontecimento(int identificação);
//nomeé o nome do utilizador que respondeu ao anúncio:Método invocado quando o utilizador pede a lista de notícias:
void registaRespostaAAnúncio(string const& nome, Data const& data_da_resposta);
//
void mostra() const;
private:
list<Notícia*> noticias;
};
Cada notícia contém:
Existem dois tipos concretos de notícias: anúncios e divulgação de acontecimentos.
Os anúncios são notícias que requerem uma resposta. A disponibilização de um anúncio, que no máximo dura todo o intervalo de validade, cessa logo que algum utilizador lhe responde. Cada anúncio contém o nome do utilizador que lhe respondeu e a data em que tal aconteceu. Esta informação é enviada a outro sistema antes da remoção do anúncio (esta operação não é da responsabilidade desta aplicação).
A divulgação de acontecimentos é uma notícia que indica a realização de um evento (e.g., um seminário). Os acontecimentos são noticiados durante todo o intervalo de validade definido.
Os acontecimentos podem ser cancelados. Nesse caso os acontecimentos continuam a ser noticiados até expirar o prazo de validade do acontecimento alertando, no entanto, para o seu cancelamento.
Considere a existência de uma classe Data onde se encontram
todas operações de que necessite para a resolução destas perguntas desta
questão.
2.1 Defina as classes Notícia, Anúncio
e Acontecimento. Não é necessário nesta alínea definir quaisquer
métodos das classes.
[cotação: 3]
2.2 Assuma que a invocação do método void
Notícia::mostra() const faz aparecer informação no ecrã com o
seguinte aspecto:
Identificação: 1
Título: Prova de kart
Descrição: Informa-se que dia 2001/07/07 decorrerá uma prova de kart no kardódromo de Palmela.
Fonte: Bruno Abreu
Data de registo: 2001/07/02
Data inicial de transmissão: 2001/07/03
Data final de transmissão: 2001/07/06
Implemente o método void Acontecimento::mostra() const,
que mostra no ecrã informação relativa a um acontecimento. Caso o
acontecimento tenha sido cancelado, a informação enviada para o ecrã tem o
seguinte aspecto:
CANCELADO: 2001/07/04
Identificação: 1
Título: Prova de kart
Descrição: Informa-se que dia 2001/07/07 decorrerá uma prova de kart no kardódromo de Palmela.
Fonte: Bruno Abreu
Data de registo: 2001/07/02
Data inicial de transmissão: 2001/07/03
Data final de transmissão: 2001/07/06
Caso o acontecimento não tenha sido cancelado, a informação enviada para o ecrã tem o seguinte aspecto:
Identificação: 1
Título: Prova de kart
Descrição: Informa-se que dia 2001/07/07 decorrerá uma prova de kart no kardódromo de Palmela.
Fonte: Bruno Abreu
Data de registo: 2001/07/02
Data inicial de transmissão: 2001/07/03
Data final de transmissão: 2001/07/06
[cotação: 2]
2.3 Implemente o destrutor da classe GestorDeNotícias.
Este método é responsável pela destruição de todas as variáveis dinâmicas
contidas nesta classe, tenham ou não sido criadas dentro dela (i.e., pelos seus
métodos).
[cotação: 2]
2.4 Implemente o método void GestorDeNotícias::actualiza(Data
const& data_actual). Este método é responsável por
actualizar as notícias disponíveis na aplicação. Lembre-se que esta
aplicação é responsável pela actualização das notícias disponíveis para
consulta, analisando diariamente as condições necessárias à
disponibilização de notícias: as notícias que não verifiquem as condições
são removidas da lista gerida por esta aplicação. Implemente todos os
métodos das classes Notícia, Anúncio e Acontecimento
que forem necessários.
[cotação: 3]
Questão 3
Implemente o método void ListaDouble::transfereDe(ListaDouble&
outra_lista), pertencente à classe ListaDouble, cuja
definição é fornecida em anexo. O método em questão transfere todos
os itens de outra_lista para o fim da lista implícita. A outra_lista
fica vazia. Não use as classes iteradoras na implementação deste
método: use manipulações de ponteiros. Use tão poucas manipulações
de ponteiros quanto possíveis.
A implementação da lista baseia-se no conceito de cadeia duplamente ligada com guardas.
[cotação: 3]
Questão 4
Exemplifique sumariamente o lançamento e a captura de uma excepção em C++ e explique para que servem e em que circunstâncias devem ser usadas.
[cotação: 2]
Anexo 1
Definição da classe ListaDouble:
#ifndef LISTA_DOUBLE_H@brief Representa listas de itens do tipo Item.
#define LISTA_DOUBLE_H
#include <iostream>
/**Item é actualmente é um sinónimo de
double, mas que pode ser alterado
facilmente para o tipo que se entender. Por convenção, chama-se "frente"
e "trás" ao primeiro e último item na lista. Os nomes "primeiro", "último",
"início" e "fim" são reservados para iteradores.
@invariant 0 <numero_de_itens.*/@brief Operador de inserção de listas num canal.
class ListaDouble {
public:
typedef double Item;
class Iterador;
class IteradorConstante;
ListaDouble();
~ListaDouble();
Item const& frente() const;
Item const& trás() const;
int comprimento() const;
bool estáVazia() const;
bool estáCheia() const;
IteradorConstante primeiro() const;
IteradorConstante último() const;
IteradorConstante início() const;
IteradorConstante fim() const;
IteradorConstante primeiraOcorrênciaDe(Item const& item) const;
IteradorConstante últimaOcorrênciaDe(Item const& item) const;
Item& frente();
Item& trás();
void põeNaFrente(Item const& novo_item);
void põeAtrás(Item const& novo_item);
void insereAntes(Iterador const& iterador, Item const& novo_item);
void insereAntes(IteradorConstante const& iterador, Item const& novo_item);
void tiraDaFrente();
void tiraDeTrás();
void esvazia();
void remove(Iterador& iterador);
void remove(IteradorConstante& iterador);
void remove(Iterador const& iterador);
void remove(IteradorConstante const& iterador);
void transfereDe(ListaDouble& outra_lista);
ListaDouble& operator += (ListaDouble const& outra_lista);
Iterador primeiro();
Iterador último();
Iterador início();
Iterador fim();
Iterador primeiraOcorrênciaDe(Item const& item);
Iterador últimaOcorrênciaDe(Item const& item);
private:
bool cumpreInvariante() const;
void poe(Elo* elo_anterior, Elo* elo_seguinte, Item const& novo_item);
void tira(Elo* elo_a_tirar);
struct Elo {
Elo(Elo* anterior = 0, Elo* seguinte = 0, Item const& item = Item());
Item item;
Elo* anterior;
Elo* seguinte;
};
int número_de_itens;
Elo* elo_inicial;
Elo* elo_final;
friend Iterador;
friend IteradorConstante;
};
/**
Todos os itens da lista são inseridos por ordem entre parênteses e separados por vírgulas.*/
std::ostream& operator << (std::ostream& saída, ListaDouble const& lista);
#include "lista_double_impl.H"
#endif // LISTA_DOUBLE_H