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.