#include <iostream>deve escrever no ecrãusing namespace std;
// definição de troca()...
int main()
{
int i1 = 1, i2 = 2;
troca(i1, i2);
cout << i1 << ' ' << i2 << endl;
}
2 1Teste o procedimento usando o programa acima.
1.b) Sobrecarregue o procedimento com uma versão para float e outra para string. Teste-as acrescentando código apropriado à função main().
1.c) Converta as três versões do procedimento por um único modelo (ou template) de procedimento. Teste-o compilando e executando o programa sem alterar a função main(). Depois experimente parametrizar explicitamente o modelo durante a invocação (i.e., troca<int>(i, j) em vez de troca(i, j)). Que forma prefere? Será sempre possível?
1.d) A implementação do modelo de procedimento troca<>() que desenvolveu provavelmente faz uso de uma variável auxiliar. Reescreva-o, se for necessário, de modo a que a definição da variável auxiliar seja separada da atribuição do seu valor *:
T aux;Crie uma classe Evento que guarda um valor para o instante de tempo do evento, não possui construtor por omissão, e se pode escrever num canal de saída:
aux = ...;
class Evento {Acrescente à função main() um teste do modelo troca<>() usando esta classe. Experimente compilar. Porque ocorreu o erro? Interprete-o e conclua acerca das restrições impostas implicitamente pelo modelo ao tipo do seu parâmetro.
public:
Evento(double tempo)
: tempo_(tempo) {
}
double tempo() const {
return tempo_;
}
private:
double tempo_;
};std::ostream& operator << (std::ostream& saida, Evento const& e) {
return saida << e.tempo();
}
* Isto não segnifica que se recomende fazê-lo, pelo contrário! As variáveis devem ser inicializadas logo que possível com valores significativos!
2. Pretende-se neste exercício artilhar um pouco as matrizes clássicas do C++. Estas matrizes têm um conjunto de problemas:
Nota: Em C++ chama-se "agregado" a uma classe ou estrutura sem construtores fornecidos explicitamente, sem membros privados ou protegidos, sem classes base e sem funções ou procedimentos virtuais. As matrizes também são consideradas agregados. Um agregado pode ser inicializado colocando uma lista de valores entre chavetas, servindo cada valor para inicializar os elementos do agregado por ordem. Elementos de um agregado para o qual não se forneça nenhum valor no inicializador serão inicializados pelo construtor por omissão do tipo. Se existirem agregados dentro de agregados os valores na lista podem consistir em inicializadores da mesma forma. Os parênteses destes inicializadores internos podem ser omitidos desde que contenham valores para todos os elementos do respectivo agregado. Por exemplo:
int m[3] = {1, 3}; // m[0] = 1, m[1] = 3 e m[2] = 0.2.a) Defina uma classe Matriz que represente uma matriz de 10 double. Defina os operadores auxiliares que forem necessários. Requisitos:struct A {
int i;
int j;
};A a = {-1, 4}; // a.i = -1 e a.j = 4.
struct B {
A a;
int m[3];
};B b = {{10, 20}, {}}; // b.a.i = 10, b.a.j = 20, b.m[0] = 0, b.m[1] = 0 e b.m[2] = 0.
B c = {10, 20, 0, 0, 0}; // o mesmo que b!
#include "matriz.H"2.b) Converta a classe desenvolvida para uma classe modelo Matriz<> que permita definir matrizes com qualquer número de elementos e de qualquer tipo. O primeiro parâmetro do modelo deve ser o tipo dos elementos e o segundo deve ser o tamanho da matriz.#include <iostream>
using namespace std;
int main()
{
Matriz m = {1.1, 2.2, 3.3};for(int i = 0; i != m.tamanho(); ++i)
cout << m[i] << ' ';
cout << endl;for(double* i = m; i != m + m.tamanho(); ++i)
cout << *i << ' ';
cout << endl;m[0] = 4.4;
Matriz const mc = m;
if(m != mc)
cout << "Falhou! A igualdade entre matrizes está mal feita!"
<< endl;m[0] = 1.1;
if(m >= mc)
cout << "Falhou! A comparação entre matrizes está mal feita!"
<< endl;for(int i = 0; i != mc.tamanho(); ++i)
cout << mc[i] << ' ';
cout << endl;for(double const* i = mc; i != mc + mc.tamanho(); ++i)
cout << *i << ' ';
cout << endl;m[1000] = 10; // Erro de execução! Índice fora dos limites!
mc[1] = 4.4; // Erro de compilação! "assignment of read-only location".
}
2.c) Escreva uma função modelo soma<> que permita calcular a soma dos elementos de uma qualquer matriz modelo Matriz<>. Use o seguinte programa de teste:
#include "matriz.H"3.a) Escreva um modelo maximo<>() para cálculo do máximo de dois valores. Teste o modelo com o seguinte programa:#include <iostream>
#include <string>using namespace std;
// Defina aqui a função modelo soma<>.
int main()
{
Matriz<string, 3> mensagens = {"Isto ", "é", " um teste marado!"};cout << soma(mensagens) << endl;
}
#include <iostream>3.b) Acrescente ao programa a classe Evento do exercício 1. e o respectivo teste do modelo maximo<>():using namespace std;
// definição de maximo<>()...
int main()
{
int i1 = 1, i2 = 2;
cout << maximo(i1, i2) << endl;double d1 = 10.0, d2 = 2.0;
cout << maximo(d1, d2) << endl;
}
#include <iostream>Compile. Interprete o erro obtido. Elimine o erro definindo o operador em falta (um evento é maior que outro se tiver lugar mais cedo). Teste de novo.using namespace std;
// definição de maximo<>()...
class Evento {
public:
Evento(double tempo)
: tempo_(tempo) {
}
double tempo() const {
return tempo_;
}
private:
double tempo_;
};std::ostream& operator << (std::ostream& saida, Evento const& e) {
return saida << e.tempo();
}int main()
{
int i1 = 1, i2 = 2;
cout << maximo(i1, i2) << endl;double d1 = 10.0, d2 = 2.0;
cout << maximo(d1, d2) << endl;Evento e1(3.3), e2(10.0);
cout << maximo(e1, e2) << endl;
}
3.c) Suponha que se pretende usar o modelo maximo<>() como se segue.
#include <iostream>Que deve resultar em:using namespace std;
// definição de maximo<>()...
int main()
{
cout << maximo(10, 20) << endl;int i1 = 1, i2 = 2;
// Pôr o maior a zero:
maximo(i1, i2) = 0;
cout << i1 << ' ' << i2 << endl;
}
20Experimente compilar este programa. Que sucedeu? Como conseguir que este programa compile?
1 0