Recibo, frequência tipo, 2ºsemestre de 1998/99, Programação II/Programação Orientada por Objectos, ISCTE:
Nome: _______________________________________________
Nº ______________________
Ass. Docente: ________________________________________

Identificação

Nome: _______________________________________________
Nº ________________
Turma: ____________

ISCTE - IGE/ETI

Programação II /Programação Orientada por Objectos

Frequência tipo

1998/1999, 2º semestre


Notas:

Questão 1
Assinale com V (Verdadeiro) as respostas que estão correctas e com F (Falso) as que estão incorrectas.

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.

Qualquer alínea pode ter zero ou mais respostas correctas. Cada resposta correctamente assinalada vale 0,5 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:

class X {
  public:
    ...
};

class A {
    int a;
    X* px;
  public:
    A();
    ~A();
    virtual void g() const {
        cout << "Execução de A::g(). ";
    }
    ...
};

class B: public A {
  public:
    B();
    void g() const {
        cout << "Execução de B::g(). ";
    }
    ...
};

int main() {
    ...
}

Questão 1.1
Dadas as declarações:
int m[10];
int* p;
Quais das seguintes sequências de instruções estão correctas quer do ponto de vista sintáctico quer do ponto de vista lógico?
__ p = m; delete p;
__ delete m;
__ p = new int[10]; delete p;
[1.5 valores]
Questão 1.2
Sendo o construtor da classe A definido por:
A::A() : a(0), px(new X) {
}
quais os destrutores adequados para esta classe?
___ A::~A() { delete a; delete px; }
___ A::~A() { delete px; }
___ A::~A() { px = new X; delete px;}
___ A::~A() { delete *px; }
[2 valores]
 Questão 1.3
Após a execução das seguintes instruções:
A* pa = new B;
B b;
B* pb = &b;
pa->g();
pb->g();
o que apareceria escrito no ecrã?
___ Execução de A::g(). Execução de B::g().
___ Execução de B::g(). Execução de B::g().
___ Execução de A::g(). Execução de A::g().
 [1.5 valores]
 Questão 2
Assuma que está completamente definida a classe Tarefa:
class Tarefa {
  public:
    // Construtores:
    Tarefa();
    Tarefa(string etiqueta, string descrição, string notas);

    // Destrutor:
    virtual ~Tarefa() {}

    // Acesso à descrição:
    string etiqueta() const;
    string descrição() const;
    string notas() const;

    // Funções membro puramente virtuais:
    virtual int duração() const = 0;
    virtual int custoMaterial() const = 0;
    virtual int custoMaoDeObra() const = 0;

  private:
    string etiqueta_;
    string descrição_;
    string notas_;
};

Assuma que está completamente definida uma classe ListaPonteiroParaTarefa cujas instâncias são listas de ponteiros para a classe Tarefa acima.  Como habitualmente, esta classe possui uma classe embutida Iterador para iterar ao longo dos seus itens.

Defina uma classe TarefaComposta tal que as suas instâncias sejam constituídas por um conjunto de ponteiros para várias tarefas que não têm dependências entre si.  Deve ser possível verificar se uma tarefa, dada a respectiva etiqueta, faz parte do conjunto de tarefas duma tarefa composta.  Deve também ser possível adicionar uma tarefa ao seu conjunto de tarefas, dado um ponteiro para a tarefa a adicionar.  A classe TarefaComposta não deve ser abstracta, mas sim concreta.

Não é necessário nesta alínea implementar qualquer um dos métodos da classe TarefaComposta.

 [4 valores]

Questão 3
Defina o método int TarefaComposta::duração() de modo a que a duração devolvida seja a maior das durações das tarefas existentes numa TarefaComposta.

 [3 valores]

Defina o método da TarefaComposta que, dada uma etiqueta, verifica se existe nessa tarefa uma outra com essa etiqueta.

 [3 valores]

 Questão 4
Assumindo que a estrutura No é definida do modo seguinte :
struct No {
    typedef int Item;

    // Não existe ponteiro para o nó anterior!
    No* seguinte;           // ponteiro para o nó seguinte.
    Item item;              // guarda o item propriamente dito.

    No(No* seg = 0, const Item& it = Item());
};

defina o procedimento
void insereOrdenadamente(No* inicial, No* final, const Item& item);
que insere ordenadamente um novo No contendo o item itemna posição correcta, de modo a manter a ordenação.  Assume-se que a ordem é crescente e que o conjunto de nós entre inicial e final é (simplesmente) ligado e está ordenado.

Assuma que os nós apontados por inicial e final são guardas, i.e., não contêm dados válidos.

 [3 valores]

Questão 5
Explique sucintamente as vantagens da utilização de listas duplamente ligadas face às simplesmente ligadas.

[2 valores]