Sobrecarga do operador de parênteses. Um bom

exemplo da sobrecarga do operador de chamada de função

() é permitir outra forma de subscrito de array duplo,

popular em algumas linguagens de programação. Em vez

de dizer

tabuleiroXadrez[ linha ][ coluna ]

para um array de objetos, sobrecarregue o operador de

chamada de função para permitir a forma alternativa

tabuleiroXadrez( linha, coluna )

Crie uma classe DoubleSubscriptedArray que tenha

recursos semelhantes à classe Array nas figuras 19.6

e 19.7. No momento da construção, a classe deverá ser

capaz de criar um array de qualquer número de linhas

e qualquer número de colunas. A classe deverá fornecer

operator() para realizar operações de duplo subscrito.

Por exemplo, em um DoubleSubscriptedArray de 3

por 5 chamado a, o usuário poderia escrever a(1, 3)

para acessar o elemento na linha 1 e coluna 3. Lembre-

-se de que operator() pode receber qualquer número

de argumentos. A representação básica do array de duplo

subscrito deve ser um array de único subscrito de inteiros

números de linhas * colunas de elementos. A função

operator() deverá realizar a aritmética de ponteiro

apropriada para acessar cada elemento do array. Deverá

haver duas versões de operator() — uma que retorne

int & (de modo que um elemento de um Double-

SubscriptedArray possa ser usado como um lvalue)

e uma que retorne const int &. A classe também deve

oferecer os seguintes operadores: ==, !=, =,

o array no formato de linha e coluna) e >> (para

receber o conteúdo inteiro do array).

Passo 1

Vamos criar o DoubleSubscriptedArray que conterá uma implementação de array de subscrito simples de um array 2D com operações básicas de subscrito duplo.

Para começar, vamos declarar a classe no arquivo de cabeçalho "DoubleSubscriptedArray.h" da seguinte forma:

#ifndef H_DOUBLESUBSCRIPTEDARRAY_H

#define H_DOUBLESUBSCRIPTEDARRAY_H

#include

using namespace std;

class DoubleSubscriptedArray {

friend ostream &operator

const DoubleSubscriptedArray&);

friend istream &operator>>(istream&,

DoubleSubscriptedArray&);

public:

DoubleSubscriptedArray(int rows = 2, int columns = 5);

DoubleSubscriptedArray(const DoubleSubscriptedArray&);

~DoubleSubscriptedArray();

int getSize() const;

int& operator()(int row, int col);

const int& operator()(int row, int col) const;

bool operator==(const DoubleSubscriptedArray&) const;

bool operator!=(const DoubleSubscriptedArray&) const;

DoubleSubscriptedArray& operator=(

const DoubleSubscriptedArray&);

private:

int rows;

int columns;

int *ptr;

};

#endif

Agora, vamos implementar a classe em seu arquivo fonte "DoubleSubscriptedArray.cpp".

Começando com o cabeçalho do arquivo e o construtor da classe que terá uma validação simples dos valores passados:

#include "DoubleSubscriptedArray.h"

DoubleSubscriptedArray::DoubleSubscriptedArray(

int linhas, int colunas) {

if (linhas > 0 && colunas > 0) {

this->linhas = linhas;

this->colunas = colunas;

ptr = new int[linhas * colunas];

}

outro {

isto->linhas = 2;

this->colunas = 5;

ptr = new int[linhas * colunas];

}

}

...

Agora, o construtor de cópia.

Primeiramente, usaremos a função getSize() para obter o tamanho do ptr para que possamos alocar memória suficiente para o novo array que definiremos:

DoubleSubscriptedArray::DoubleSubscriptedArray(

const DoubleSubscriptedArray & toCopy) {

int size = toCopy.getSize();

ptr = new int[size];

...

}

Em seguida, itere pelas matrizes, inicializando os valores para corresponder ao objeto correto:

DoubleSubscriptedArray::DoubleSubscriptedArray(

const DoubleSubscriptedArray & toCopy) {

...

for (int i = 0; i

ptr[i] = toCopy.ptr[i];

}

O destruidor de classe deve usar a palavra-chave delete[] para desalocar o array ptr alocado dinamicamente da seguinte forma:

DoubleSubscriptedArray::~DoubleSubscriptedArray() {

delete[] ptr;

}

Passo 2

A função getSize() simplesmente retorna o produto das linhas e colunas, o que essencialmente resulta no tamanho do array ptr:

int DoubleSubscriptedArray::getSize() const {

return rows * columns;

}

A sobrecarga de operator() validará os valores passados e, em seguida, retornará o elemento correspondente executando a aritmética correta de uma matriz 2D da seguinte maneira:

int &DoubleSubscriptedArray::operator()(int row, int col)

{

if (rows

{

cout

exit(1);

}

return ptr[row * columns + col];

}

const int &DoubleSubscriptedArray::operator()(

int row, int col) const {

if (rows

{

cout

exit(1);

}

return ptr[row * columns + col];

}

A sobrecarga do operador== compara os dois objetos primeiro comparando os tamanhos e, em seguida, os elementos da seguinte forma:

bool DoubleSubscriptedArray::operator==(

const DoubleSubscriptedArray &right) const {

if (rows == right.rows && columns == right.columns)

{

for (int i = 0; i

if (ptr[i] != right.ptr[i])

return false;

return true;

}

return false;

}

A sobrecarga do operador!= utiliza a sobrecarga do operador definida anteriormente da seguinte forma:

bool DoubleSubscriptedArray::operator!=(

const DoubleSubscriptedArray &right) const {

return !operator==(right);

}

A sobrecarga do operador de atribuição compara primeiro as referências de objeto para ver se o valor do objeto deve ser modificado ou não:

DoubleSubscriptedArray &DoubleSubscriptedArray::operator=(

const DoubleSubscriptedArray &right) {

if (&right != this)

{

...

}

...

}

Em seguida, veja se a memória alocada dinamicamente do ponteiro ptr deve ser realocada se as memórias não corresponderem:

DoubleSubscriptedArray &DoubleSubscriptedArray::operator=(

const DoubleSubscriptedArray &right) {

if (&right != this)

{

if (rows == right.rows

&& columns == right.columns)

{

delete[] ptr;

ptr = new int[right.getSize()];

}

...

}

...

}

Passo 3

Por fim, itere pelo array, inicializando os valores do array do objeto modificado. Além disso, retorne a referência do objeto para habilitar o encadeamento de operações.

DoubleSubscriptedArray &DoubleSubscriptedArray::operator=(

const DoubleSubscriptedArray &right) {

if (&right != this)

{

...

for (int i = 0; i

ptr[i] = right.ptr[i];

}

return *this;

}

A sobrecarga de operador

Certifique-se de retornar o objeto ostream para permitir o encadeamento de outras expressões de saída.

ostream &operator

ostream &output, const DoubleSubscriptedArray &a)

{

for (int i = 0; i

{

for (int j = 0; j

output

output

}

return output;

}

A sobrecarga do operador>> também utiliza o recurso de subscrições duplas tge para acessar os elementos correspondentes, inicializando-os com os valores inseridos:

istream &operator>>(

istream &input, DoubleSubscriptedArray &a) {

for (int i = 0; i

for (int j = 0; j

input >> a(i, j);

return input;

}

Passo 4

O principal para fins de demonstração:

#include

#include "DoubleSubscriptedArray.h"

using namespace std;

int main()

{

DoubleSubscriptedArray* arr1

= new DoubleSubscriptedArray;

DoubleSubscriptedArray* arr2

= new DoubleSubscriptedArray(3, 3);

cin >> *arr1 >> *arr2;

cout

arr1 = arr2;

if (arr1 == arr2)

cout

if (arr1 != arr2)

cout

}

Resposta

Ver desenvolvimento.