Template de classe Array. Use um parâmetro não
tipo de template int númeroDeElementos e um parâmetro
de tipo tipoElemento para ajudar a criar um
template para a classe Array (figuras 19.6 e 19.7) que
desenvolvemos no Capítulo 19. Esse template permitirá
que objetos Array sejam instanciados com um número
especificado de elementos de um tipo de elemento especificado
no tempo de compilação.
Escreva um programa com template de classe Array.
O template pode instanciar um Array de qualquer tipo
de elemento. Sobreponha o template com uma definição
específica para um Array de elementos float (class
Array
de um Array de int pelo template, e deverá mostrar
que uma tentativa de instanciar um Array de float usa
a definição fornecida na class Array
Passo 1
Vamos criar uma classe de modelo Array com a especialização explícita para o tipo de dados float.
A classe será declarada e implementada dentro do arquivo de cabeçalho, mas a especialização explícita terá suas definições de função de membro (implementação) no arquivo de origem.
Array.h
Cabeçalho do arquivo (usaremos a constante definida na especialização explícita):
#ifndef H_ARRAY_H
#define H_ARRAY_H
#include
#include
#include
using namespace std;
const int SIZE = 5;
...
Passo 2
O template que vamos usar consiste em um parâmetro non-type e um parâmetro type:
template
As funções de amigo devem ser declaradas fora da classe para não ofuscar a declaração do modelo de classe. Teremos que declarar a classe para usar o tipo nos cabeçalhos das funções:
template
class Array;
template
ostream &operator
const Array
template
istream &operator>>(istream &,
Array
Agora, a declaração de classe com os protótipos da função amigo (certifique-se de adicionar os parâmetros do modelo padrão):
template
class Array {
friend ostream &operator(ostream &, const Array &);
friend istream &operator>>(istream &, Array &);
...
};
O resto da declaração da classe:
template
class Array {
...
public:
Array();
Array(const Array &);
~Array();
int getSize() const;
const Array &operator=( const Array & );
bool operator==( const Array & ) const;
bool operator!=( const Array &right ) const
{
return ! ( *this == right );
}
elementType &operator[]( int );
elementType operator[]( int ) const;
private:
int size;
elementType* ptr;
};
Passo 3
Agora, vamos implementar as funções de membro (certifique-se de adicionar a declaração do modelo e usar corretamente o tipo Array nos cabeçalhos - adicionando os parâmetros do modelo).
Os construtores:
template
Array
size = (numberOfElements > 0 ? numberOfElements : 10);
ptr = new elementType[size];
for (int i = 0; i
ptr[i] = 0;
}
template
Array
const Array &arrayToCopy)
: size(arrayToCopy.size) {
ptr = new elementType[size];
for (int i = 0; i
ptr[i] = arrayToCopy.ptr[i];
}
O destruidor:
template
Array
delete[] ptr;
}
A função de membro getter:
template
int Array
const {
return size;
}
A função operador= sobrecarga:
template
const Array
&Array
const Array &right) {
if (&right != this)
{
if (size != right.size)
{
delete[] ptr;
size = right.size;
ptr = new elementType[size];
}
for (int i = 0; i
ptr[i] = right.ptr[i];
}
return *this;
}
O operador == função de sobrecarga:
template
bool Array
const Array &right) const {
if (size != right.size)
return false;
for (int i = 0; i
if (ptr[i] != right.ptr[i])
return false;
return true;
}
Passo 4
As funções de sobrecarga do operador[]:
template
elementType &Array
::operator[](
int subscript) {
if (subscript = size)
{
cerr
exit(1);
}
return ptr[subscript];
}
template
elementType Array
::operator[](
int subscript) const {
if (subscript = size)
{
cerr
exit(1);
}
return ptr[subscript];
}
A função de sobrecarga operador
template
ostream &operator
const Array
int i;
for (i = 0; i
{
output
if ((i + 1) % 4 == 0)
output
}
if (i % 4 != 0)
output
return output;
}
O operador >> função de sobrecarga:
template
istream &operator>>(istream &input,
Array
for (int i = 0; i
input >> a.ptr[i];
return input;
}
Agora, a especialização explícita do modelo de classe.
A especialização segue o modelo de classe genérico (primário). É uma declaração de classe independente que tem sua implementação armazenada no arquivo fonte.
Defina a especialização nos argumentos do modelo que seguem a declaração da classe:
template
class Array
O restante da declaração de especialização explícita:
template
ostream &operator
const Array
template
istream &operator>>(istream &,
Array
template
class Array {
friend ostream &operator
friend istream &operator>>(istream &, Array &);
public:
Array();
Array(const Array &);
~Array();
int getSize() const;
const Array &operator=( const Array & );
bool operator==( const Array & ) const;
bool operator!=( const Array &right ) const
{
return ! ( *this == right );
}
float &operator[]( int );
float operator[]( int ) const;
private:
int size;
float* ptr;
};
Array.cpp
Para implementar a classe de especialização explícita, basta consultar o modelo de classe especializada (por exemplo, Array
Substitua cada elementType por float e certifique-se de retornar o tipo float com as funções de membro de sobrecarga do operador[].
Também adicionaremos uma instrução de saída indicando que a classe float é usada, que será usada para fins de demonstração.
Passo 5
Os construtores junto com o cabeçalho do arquivo:
#include "Array.h"
Array
cout
size = SIZE;
ptr = new float[size];
for (int i = 0; i
ptr[i] = 0;
}
Array
: size(arrayToCopy.size) {
cout
ptr = new float[size];
for (int i = 0; i
ptr[i] = arrayToCopy.ptr[i];
}
O destruidor:
Array
cout
delete[] ptr;
}
A função de membro getter:
int Array
cout
return size;
}
A função operador= sobrecarga:
const Array
const Array &right) {
cout
if (&right != this)
{
if (size != right.size)
{
delete[] ptr;
size = right.size;
ptr = new float[size];
}
for (int i = 0; i
ptr[i] = right.ptr[i];
}
return *this;
}
O operador == função de sobrecarga:
bool Array
const {
cout
if (size != right.size)
return false;
for (int i = 0; i
if (ptr[i] != right.ptr[i])
return false;
return true;
}
As funções de sobrecarga do operador[]:
float &Array
cout
if (subscript = size)
{
cerr
exit(1);
}
return ptr[subscript];
}
float Array
const {
cout
if (subscript = size)
{
cerr
exit(1);
}
return ptr[subscript];
}
O operator
ostream &operator
const Array
cout
int i;
for (i = 0; i
{
output
if ((i + 1) % 4 == 0)
output
}
if (i % 4 != 0)
output
return output;
}
O operador >> função de sobrecarga:
istream &operator>>(istream &input,
Array
cout >."
for (int i = 0; i
input >> a.ptr[i];
return input;
}
main.cpp
Breve demonstração:
#include
#include "Array.h"
using namespace std;
int main()
{
Array intArray;
cout size: "
Array floatArray;
floatArray.getSize();
cout
}
Resposta
Ver o desenvolvimento.