C++
Home

Sobrecaga de Operadores


- Sobrecarregando os operadores de inserção de stream e extração de stream

Obs sobre o código abaixo:
- Estamos sobrecarregando o operador << e >> para um tipo de set e get em uma classe.
- Iostream é utilizado para a sobrecarga de ostream e istream
- iomanip é usado para pegar somente a quantidade correta de texto, no caso 29, um fica para o /0
- não tem como mudar o nome da função friend para sobrecarga

no mais, leia o código e tente entender

#include <iostream>
#include <iomanip>

class Nome {

  friend std::ostream &operator<<( std::ostream&, const Nome & );
  friend std::istream &operator>>( std::istream&, Nome & );


  private:
    char nome[30];
};

std::ostream &operator<<( std::ostream &texto, const Nome &aNome )
{
  texto << " - " << aNome.nome << " - ";
  return texto;
}

std::istream &operator>>( std::istream &texto, Nome &aNome )
{
  //texto.ignore(); ignora numero de letras
  
  texto >> std::setw(30) >> aNome.nome;
  return texto;
}

 

int main()
{
  Nome aNome;

  std::cout << "Digite uma palavra: " << std::endl;

  std::cin >> aNome;

  std::cout << "A palavra digita é: " << aNome << std::endl;

  system("pause");

  return 0;
}

Fazendo o código acima funcionar, percebi que o exemplo estava instanciando a classe sem ponteiros.
Então, pensei como ficaria com ponteiros e escrevi o código abaixo..
Se vc tentar usar o código acima e instanciar a classe com ponteiro, vai ver que o resultado
fica todo tosco hahaha ( nao se esqueça de liberar a memoria )

#include <iostream>
#include <iomanip>

class Nome {

  friend std::ostream &operator<<( std::ostream&, const Nome & );
  friend std::istream &operator>>( std::istream&, Nome & );

  friend std::ostream &operator<<( std::ostream&, const Nome * );
  friend std::istream &operator>>( std::istream&, Nome * );

  private:
    char nome[30];

};

std::ostream &operator<<( std::ostream &texto, const Nome &aNome )
{
  texto << " - " << aNome.nome << " - ";
  return texto;
}

std::istream &operator>>( std::istream &texto, Nome &aNome )
{
  //texto.ignore(); ignora numero de letras
  texto >> std::setw(30) >> aNome.nome;
  return texto;
}

std::ostream &operator<<( std::ostream &texto, const Nome *aNome )
{
  texto << " - " << aNome->nome << " - ";
  return texto;
}

std::istream &operator>>( std::istream &texto, Nome *aNome )
{
  //texto.ignore(); ignora numero de letras
  texto >> std::setw(30) >> aNome->nome;
  return texto;
}

int main()
{
  Nome aNome;   

  std::cout << "Digite uma palavra: " << std::endl;

  std::cin >> aNome;

  std::cout << "A palavra digita é: " << aNome << std::endl;

  Nome *aNome2 = new Nome;

  std::cout << "Digite uma palavra: " << std::endl;

  std::cin >> aNome2;

  std::cout << "A palavra digita é: " << aNome2 << std::endl;

  delete aNome2;

  system("pause");

  return 0;
}



- Sobrecarregando operadores unários

O exemplo abaixo demonstra uma adicição com uma classe..
Muito interessante mais nada intuitivo

ENTENDA O EXEMPLO DA SEGUINTE FORMA

   i = *aMat + 5;
   ou
   i = *aMat( 5 );

   fácil!

#include <iostream>

class Matematica {

  private:
    int numero;

  public:

    Matematica( int );
    ~Matematica();

  int operator +( int );
};

Matematica::Matematica( int a=0 )
{
  numero = a;
}

Matematica::~Matematica()
{

}

int Matematica::operator +( int n )
{
  numero = numero + n;
  return numero;
}

int main()
{

  Matematica *aMat = new Matematica(5);

  int i;

  i = *aMat + 5;

  std::cout << i << std::endl;

  delete aMat;

  system("pause");

  return 0;
}

 



- Sobrecarregando operadores binários

Um operador binário pode ser sobrecarregado com uma função membro não static, ou com uma função não membro porém com dois parametros ( um desses argumentos deve ser um objeto ou referência para objeto )

Se z e y são um objeto, então z += y é tratado por C++ como se fosse operator+=( z, y )

Exemplo ( esse foi complicado ):

#include <iostream>

class Increment {

  private:
    int i;

  public:
    Increment( int a=0 ) { i = a; }
    const Increment & operator+=( int a );
    int getI();

};

int Increment::getI()
{
  return this->i;
}

/* detalhe importante, já que é a propria classe que vai receber algo,
fica complicado de se pensar em como fazer essa função, e é por isso o uso do &,
ele deve receber uma referencia dele mesmo += a e retornar um ponteiro para
encadeamento
*/

const Increment &Increment::operator +=( const int a)
{
   this->i += a;
   return *this;
}

int main()
{

  //Increment *aInc = new Increment(10);
  Increment aInc(10);
  int a = 5;

  aInc += a;
  std::cout << aInc.getI();

  //delete aInc;

  system("pause");

  return 0;
}


- Sobrecarregando ++ e --

Para sobrecarregar incremento e decremento, a função deve ser distinta para que o compilador
saiba distinguir qual versão de ++ vc quer usar.

Para pré incremento ( ++aObjeto )

++aObjeto chama aObjeto.operator++()

e

Para pós incremento ( aObjeto++ )

aObjeto++ apresenta um nivel de dificuldade maior.

Ele gera um

aObjeto.operator++( Int=0 ) - Onde o zero é usado apenas para diferenciar o pos incremento do pre decremento.

Exemplo:

#include <iostream>

class Numeros {
  private:
    int n;

  public:
    int getN();
    Numeros operator++( int );
    Numeros &operator++();
    Numeros( int );
};

Numeros::Numeros( int a = 0 )
{
  this->n = a;
}

int Numeros::getN()
{
  return this->n;
}

Numeros &Numeros::operator ++()
{
  ++( this->n );
  return *this;
}

// detalhe da complexidade da coisa
Numeros Numeros::operator ++( int )
{
  Numeros temp = *this;
  ( this->n )++;
  return temp;
}

int main()
{

  Numeros a(1);

  a++;

  std::cout << a.getN();

  ++a;

  std::cout << a.getN();

  return 0;
}