Nome do aluno: _______________________________________________
Número do aluno: ______________________
Assinatura do docente: ________________________________________
Identificação
Nome do aluno: _______________________________________________Número do aluno: ______________________
Turma: ____________
Exame de 1 ª época
Programação Orientada para Objectos
IGE e ETI
2º semestre de 1999/2000
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.
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.
Em todos os casos em que não é explicitamente referida a localização de uma instrução, considere que esta é dada na função main() do programa seguinte:
#include <iostream>
using namespace std;class A {
public:
A(int a, int b = 0)
: a(a + b) {
}
int h() const { return a; }protected:
int a;
};class B : public A {
public:
B(int a) : A(2*a) { ba = new A(a); }
virtual int h() const { return 2*a; }
virtual ~B() {
f();
delete ba;
}
int g();private:
A* ba;
void f() const {
cout << ba->h() << endl;
}
};int main()
{
...
}
__ A a(7, 0);
__ A* a = new a(3);
__ B* b = new B();
[1,5 valores]
B* b = new B(1);qual o resultado produzido pelo programa (apenas uma das respostas está correcta)? Atenção aos procedimentos virtuais!
A* a = b;
cout << " " << b->h() << " " << a->h() << " ";
delete b;
__ 4 2 1
__ 4 4 1
__ 4 2 2
[0,5 valores]
__ A a(5); a.a = 3;
__ B* b(1); cout << b->h();
[1 valor]
__ A* p = ba;
__ int& r = a;
__ int* pi = &a;
__ A** pp = &ba;
[2 valores]
Pretende-se para isso desenvolver uma hierarquia de classes que represente os vários tipos de textos disponíveis: textos literários, científicos e jornalísticos.
No topo da hierarquia está a classe abstracta TextoEmProsa:
class TextoEmProsa {Assuma que o construtor TextoEmProsa(std:::istream& entrada) e os procedimentos mostra(), carrega() e guarda() estão já definidos algures.
public:
TextoEmProsa(std::string const& título, std::string const& autor,
int const número_de_palavras, int const número_de_frases,
int const número_de_parágrafos)
: título_(título), autor_(autor),
número_de_palavras(número_de_palavras),
número_de_frases(número_de_frases),
número_de_parágrafos(número_de_parágrafos) {
}
TextoEmProsa(std::istream& entrada);
virtual ~TextoEmProsa() {}// Devolve o tipo do texto (literário, científico ou jornalístico):
virtual string tipo() const = 0;// Facilidade de leitura do texto:
virtual double legibilidade() const {
return double(número_de_palavras)/número_de_frases;
}// Funções de inspecção:
std::string const& título() const {
return título_;
}
std::string const& autor() const {
return autor_;
}
int númeroDePalavras() const {
return número_de_palavras;
}
int númeroDeFrases() const {
return número_de_frases;
}
int númeroDeParágrafos() const {
return número_de_parágrafos;
}
// Mostra no ecrã o que é comum a todos os TextoEmProsa:
virtual void mostra() const;
// Carrega do canal entrada o que é comum a todos os TextoEmProsa:
virtual void carrega(std::istream& entrada);// Guarda no canal saida o que é comum a todos os TextoEmProsa:
virtual void guarda(std::ostream& saida) const;private:
std::string título_;
std::string autor_;
int número_de_palavras;
int número_de_frases;
int número_de_parágrafos;
};
O índice de legibilidade de um texto científico é dado pelo número médio de equações por parágrafo.
Defina todos os procedimentos e funções da classe TextoCientífico, excepto o construtor que recebe um canal de entrada (istream).
Defina também as classes TextoLiterário e TextoJornalístico, mas não especifique os seus membros, ou seja, não inclua nada entre {}. Explicite apenas se derivam de alguma outra classe. I.e., use o formato:
class B /* aqui deve especificar as heranças, se existirem. */ {[1,5 valores]
// Aqui não ponha nada!
};
Assim, deve ser introduzida uma nova classe abstracta Texto que representa qualquer tipo de texto. Deve ser ainda criada uma nova classe concreta que represente os novos textos em verso, sabendo que tanto os textos em verso, como os textos em prosa são textos.
Os textos em verso contêm o título, o autor, o número de palavras e o número de estrofes, e dispõem das respectivas funções de inspecção. O índice de legibilidade de um texto poético é 0 e o tipo é "TextoEmVerso".
Reestruture a hierarquia de classes de modo a acomodar estas alterações. A classe texto deve ser uma generalização dos textos em prosa e poéticos. Todas as classes desta hierarquia devem possuir um construtor a partir de um canal de entrada. Defina todas as classes, mas não defina nenhum dos métodos.
Tal como na alínea anterior, não especifique os membros das classes TextoLiterário e TextoJornalístico.
[2 valores]
Para definir a lista pode usar qualquer das possibilidades referidas durante as aulas: list<Texto*>, ListaPonteiroTexto ou Lista<Texto*>.
Não é necessário implementar nenhum dos métodos nesta alínea.
[1 valor]
[1 valor]
[1,5 valores]
[1 valor]
Os dados lidos do canal têm o seguinte formato:
número_de_textos[1,5 valores]
tipo_do_primeiro_texto
... informação do primeiro texto
tipo_do_segundo_texto
... informação do segundo texto
...
tipo_do_último_texto
... informação do último texto
[1 valor]
struct Elo {usada para representar os elos de uma cadeia duplamente ligada com a particularidade de ser circular, i.e., o elo seguinte do último elo da cadeia é o primeiro elo da cadeia e o elo anterior do primeiro elo da cadeia é o último elo da cadeia. A cadeia não tem guardas.
typedef int Item;Item item;
Elo* anterior;
Elo* seguinte;
};
Considere que existe um procedimento
inline void troca(Elo*& a, Elo*& b) {que troca dois ponteiros para Elo.
Elo* aux = a;
a = b;
b = aux;
}
Defina um procedimento void inverte(Elo*& primeiro) que inverta a ordem dos elos de uma cadeia duplamente ligada e circular cujo primeiro elo é apontado pelo ponteiro primeiro. Note que quando a cadeia está vazia o ponteiro para o primeiro elemento tem o valor 0. Note também que em geral o primeiro elo da cadeia passa a ser o que antes era o último.
Faça desenhos da cadeia em várias situações! Só assim resolverá com sucesso esta alínea!
[1,5 valores]
class PilhaInt {Defina a função bool PilhaInt::cheia() const. Uma pilha está cheia quando não havendo mais elementos disponíveis na matriz dinâmica, se tenta duplicar o tamanho desta matriz e tal não é possível por ter sido lançada uma excepção.
public:
typedef int Item;PilhaInt(int tamanho_inicial = tamanho_minimo); // construtor da classe.
PilhaInt(PilhaInt const& p); // construtor por cópia da classe.
~PilhaInt(); // destrutor da classe.PilhaInt& operator = (PilhaInt const& p); // atribuição por cópia da classe.
...
bool vazia() const; // devolve true sse a pilha estiver vazia.
bool cheia() const; // devolve true sse a pilha estiver cheia.
int altura() const; // devolve o número de itens na pilha....
private:
static int const tamanho_minimo = 32; // tamanho mínimo da matriz (tem de ser > 0).mutable int tamanho; // tamanho corrente da matriz.
int quantos; // número de itens actualmente na pilha.
mutable Item* itens; // matriz dinâmica dos itens.
};
Observação: a excepção lançada pelo operador new em caso de falta de memória é bad_alloc. Mas é preferível lidar com o problema para qualquer excepção.
Defina as funções e procedimentos (membros ou não) que achar necessários.
[2 valores]
[1 valor]