Você está na página 1de 5

Universidade Federal do Rio Grande do Norte

Instituto Metrpole Digital


IMD0030 Linguagem de Programao I
Docente: Umberto S. Costa

Problema: desenvolvimento de habilidades de programao na linguagem C++.

Subproblema 5: templates de classes e TADs.

Produto do subproblema: (i ) resumo das principais caractersticas e recursos C++ identificados


durante a explorao das questes deste subproblema (at duas pginas, podendo haver apndices);
(ii) respostas s questes abaixo; e (ii i) cdigo-fonte dos programas implementados.

Data de entrega via SIGAA: 28 de setembro de 2017.

Instrues: neste problema o aluno deve consultar as referncias indicadas pelo docente para se
familiarizar com os recursos necessrios criao de programas simples em C++, sem prejuzo
consulta de outras fontes como manuais e tutoriais. Usar as questes e programas mostrados a se-
guir como guia para as discusses em grupo e para orientar a explorao da linguagem C++. Para
facilitar o aprendizado, recomenda-se que o aluno compare os recursos e conceitos de C++ com
seu conhecimento prvio acerca de outras linguagens de programao. Leia e modifique os cdigos
mostrados e utilize os conceitos e recursos explorados para a criar os programas solicitados. Recur-
sos exclusivos da linguagem C devem ser ignorados e substitudos por seus correspondentes em C++.

Questes1 :

1. Considere a listagem a seguir, onde definimos um template para a classe point:


/ L i s t i n g 48 1. The p o i n t C l a s s Template / 1
template <c l a s s T> 2
c l a s s point 3
{ 4
public : 5
p o i n t (T c o n s t& x , T c o n s t& y ) 6
: x_{x } , y_{y} 7
{} 8
9
1
Em parte inspiradas em Exploring C++ 11, Ray Lischner. Alguns programas foram retirados desta mesma fonte.

1
point () 10
: x_{ } , y_{} 11
{} 12
13
T c o n s t& x ( ) 14
const 15
{ 16
r e t u r n x_ ; 17
} 18
19
T c o n s t& y ( ) 20
const 21
{ 22
r e t u r n y_ ; 23
} 24
private : 25
T x_ ; 26
T y_ ; 27
}; 28
29
i n t main ( ) {} 30

lists/list4801.cpp

Nesta listagem as funes-membro (mtodos) foram escritas utilizando diversas linhas para
destacar o fato de que elas seguem a mesma estrutura de uma funo. Perceba que, quando
os mtodos forem mais complexos e tomarem diversas linhas, os limites da definio da classe
podero ser tornar confusos. Como alternativa, podemos definir os mtodos fora da definio
da classe, conforme mostrado na listagem list4801V2.cpp, mostrada a seguir:
/ L i s t i n g 481, V2 . The p o i n t C l a s s Template / 1
template <c l a s s T> 2
c l a s s point 3
{ 4
public : 5
p o i n t (T c o n s t &, T c o n s t &); 6
point ( ) ; 7
T c o n s t& x ( ) c o n s t ; 8
T c o n s t& y ( ) c o n s t ; 9
private : 10
T x_ ; 11
T y_ ; 12
}; 13
14
t e m p l a t e < c l a s s T> 15
p o i n t <T> : : p o i n t (T c o n s t& x , T c o n s t& y ) 16
: x_{x } , y_{y} 17
{} 18
19
t e m p l a t e < c l a s s T> 20
p o i n t <T> : : p o i n t ( ) 21
: x_{ } , y_{} 22
{} 23

2
24
t e m p l a t e < c l a s s T> 25
T c o n s t& p o i n t <T> : : x ( ) 26
const 27
{ 28
r e t u r n x_ ; 29
} 30
31
t e m p l a t e < c l a s s T> 32
T c o n s t& p o i n t <T> : : y ( ) 33
const 34
{ 35
r e t u r n y_ ; 36
} 37
38
i n t main ( ) {} 39

lists/list4801V2.cpp

Observe atentamente esta nova verso da classe e perceba que o nome de cada mtodo
precedido com point<T>::, para indicar vinculao classe point, que utiliza um nome de
tipo T. Definies de mtodos internas podem ser combinadas com definies externas a uma
classe. Salve esta listagem com o nome list4801V3.cpp e acrescente dois novos mtodos:
void move_to(T x, T y); /// mova o ponto para as coordenadas (x, y)
void move_by(T x, T y); /// adicione (x, y) posio atual do ponto
Observe os comentrios para definir os novos dois mtodos, externamente definio da classe.
2. Podemos representar os n elementos de um conjunto como um vetor com n posies. Pede-se:
(a) Crie uma classe conjunto assumindo que:
i. A classe deve suportar elementos numricos. Utilize templates;
ii. A cardinalidade de um conjunto deve ser conhecida por seu construtor;
iii. Utilize nveis de acesso de forma a tornar sua classe segura;
iv. No existem repeties em um conjunto. Ignore elementos repetidos;
v. Implemente mtodos para ler conjuntos, escrever conjuntos, testar a pertinncia de
um elemento a um conjunto, calcular o conjunto resultante da diferena, da unio e
da interseo entre dois conjuntos. Crie os mtodos auxiliares que julgar necessrios;
vi. A memria reservada deve ser liberada via um destrutor adequado.
(b) Crie um programa principal que:
i. Solicite e leia dois conjuntos A e B com elementos inteiros;
ii. Compute e imprima A B, A B e A B.
3. Analise a listagem list4802.cpp, responsvel por criar um novo Tipo de Dado Abstrato (TAD)
para representar nmeros racionais:
#i n c l u d e <i o s t r e a m > 1
2
template <c l a s s T> 3
class rational 4

3
{ 5
public : 6
t y p e d e f T v alue_ty pe ; 7
r a t i o n a l ( ) : r a t i o n a l {0} {} 8
r a t i o n a l (T num) : numerator_{num} , denominator_ {1} {} 9
r a t i o n a l (T num, T den ) ; 10
11
v o i d a s s i g n (T num, T den ) ; 12
13
template <c l a s s U> 14
U convert () 15
const 16
{ 17
r e t u r n s t a t i c _ c a s t <U>(numerator ( ) ) / s t a t i c _ c a s t <U>(denominator ( ) ) ; 18
} 19
20
T numerator ( ) c o n s t { r e t u r n numerator_ ; } 21
T denominator ( ) c o n s t { r e t u r n denominator_ ; } 22
private : 23
void reduce ( ) ; 24
T numerator_ ; // numerator g e t s t h e s i g n o f t h e r a t i o n a l v a l u e 25
T denominator_ ; // denomi nator i s a l w a y s p o s i t i v e 26
}; 27
28
// C o n s t r u c t a r a t i o n a l o b j e c t , g i v e n a numerator and a denomi nator . 29
template <c l a s s T> 30
r a t i o n a l <T> : : r a t i o n a l (T num, T den ) 31
: numerator_{num} , denominator_ { den } 32
{ 33
r a t i o n a l <T> : : r e d u c e ( ) ; 34
} 35
36
// A s s i g n a numerator and a denominator , t h e n r e d u c e t o normal form . 37
template <c l a s s T> 38
v o i d r a t i o n a l <T> : : a s s i g n (T num, T den ) 39
{ 40
numerator_ = num ; 41
denominator_ = den ; 42
r a t i o n a l <T> : : r e d u c e ( ) ; 43
} 44
45
// Reduce t h e numerator and denomi nator by t h e i r GCD. 46
template <c l a s s T> 47
v o i d r a t i o n a l <T> : : r e d u c e ( ) { } 48
49
// Compare two r a t i o n a l numbers f o r e q u a l i t y . 50
template <c l a s s T> 51
b o o l o p e r a t o r==( r a t i o n a l <T> c o n s t& a , r a t i o n a l <T> c o n s t& b ) 52
{ 53
r e t u r n a . numerator ( ) == b . numerator ( ) and 54
a . denominator ( ) == b . denominator ( ) ; 55
} 56

4
57
// Compare two r a t i o n a l numbers f o r i n e q u a l i t y . 58
template <c l a s s T> 59
i n l i n e b o o l o p e r a t o r !=( r a t i o n a l <T> c o n s t& a , r a t i o n a l <T> c o n s t& b ) 60
{ 61
r e t u r n not ( a == b ) ; 62
} 63
64
i n t main ( ) { 65
r a t i o n a l <s h o r t > z e r o { } ; 66
r a t i o n a l <i n t > p i 1 { 3 5 5 , 1 1 3 } , x { 1 , 2 } , y { 2 , 4 } ; 67
r a t i o n a l <long > p i 2 {80143857 L , 25510582 L } ; 68
69
i f ( x == y ) 70
s t d : : c o u t << " 1/2 == 2/4 " << s t d : : e n d l ; 71
else 72
s t d : : c o u t << " 1/2 != 2/4 " << s t d : : e n d l ; 73
} 74

lists/list4802.cpp

Neste TAD, o tipo do numerador e do denominador parametrizado via template, de forma que
o usurio pode usar os tipos short, int ou long, de acordo com a preciso desejada. Pede-se:
(a) Observe a conveno utilizada na linha 7, onde o typedef usado para acessar o parmetro
do template de uma forma padronizada. Por exemplo, vector<char>::value_type um
typedef para char. Esta linha pode ser omitida caso no desejemos seguir tal padro.
Salve e compile esta listagem utilizando o nome list4802V2.cpp.
(b) Note, nas linhas 14 a 19, a definio de um template que utiliza um segundo parmetro
para o mtodo convert(). O que significa o a palavra-chave static_cast? Mostre um
exemplo de uso do mtodo convert().
(c) Os resultados de execuo das linhas 70 a 73 da listagem list4802.cpp so os espera-
dos? O que deu errado? Corrija este problema definindo o mtodo reduce() na listagem
list4802V2.cpp. Dica: crie uma funo privada para calcular o MDC do numerador e do
denominador do racional a ser reduzido, ela poder auxiliar nos clculos a serem feitos.
(d) Qual o efeito do uso da palavra-chave inline (linha 60)?
(e) Nas linhas 51 a 63 duas funes independentes da classe so definidas como operadores
sobrecarregados de igualdade e diferena entre operandos do tipo rational<T>, enquanto
na linhas 70 usa-se um desses operadores. Modifique seu programa list4802V2.cpp para
incluir os operadores <, , >, sobre o tipo rational<T>. Teste seus novos operadores.
4. Salve a ltima verso da listagem list4802V2.cpp como list4803.cpp.
(a) Inclua, na listagem list4803.cpp, operadores aritmticos unrios e binrios.
(b) Qual o resultado se utilizarmos a seguinte funo principal em list4803.cpp?
int main() {
rational<int> r{(rational<int>)3 * rational<int>{1, 3}};
std::cout << r.numerator() << / << r.denominator() << std::endl;
}