Ajude nosso projeto a se manter online.

Sobrecarga (Overloading) de Operadores em C++

 Neste tutorial de nosso curso de C++, vamos aprender como sar uma importantíssima ferramenta da linguagem C++, a sobrecarga de operadores.


A função de um operador

O que faz o operador '+' no comando:
2+2 ?

Moleza. Ele soma, afinal, é o operador de adição.

Errado. Ele não é o operador de adição.
Então, o que é?

Depende do uso!

Por exemplo, com strings:
"C++" + "Progressivo"

Vai resultar na string: "C++ Progressivo"
Ou seja, a função do operador '+' foi de concatenação, ou seja, unir, juntar duas strings em uma só. Veja bem, é concatenar, não faz sentido 'somar texto'. Se soma números, e com números, a função do '+' é de adição matemática.

Ou seja, um operador pode agir de diferentes maneiras, dependendo de como está sendo usado. É chamada sobrecarga.


Para que serve a sobrecarga de Operador

Vamos supor que você é o programador de uma empresa que administra várias bandas, dentre elas tem a banda 'IronMaiden', objeto da classe 'Banda'. Seu sistema também tem a classe "Membro", onde seus objetos são os membros de cada banda.

Sobrecarga de operadores em C++

Vamos supor que o candidato "BruceDickinson" vai ser contratado e o membro "BlazeBayley" vai sair da banda.

Com sobrecarga de operadores, podemos usar o operador '+' na expressão:
IronMaiden = IronMaiden + BruceDickinson

Bem como usar o '-' no comando:
IronMaiden = IronMaiden - BlazeBayley

Olha que curioso: estamos somando um objeto do tipo Banda com um objeto do tipo Membro. Mas, não faz sentido? Um vai entrar e outro vai sair.

Outro exemplo, imagina que você é o programador responsável por uma grande companhia.

Quando contratamos, estamos adicionando alguém, então podemos fazer uma sobrecarga para somar um objeto da classe Funcionario com o objeto da classe Empresa, aí lá no seu código, quando isso ocorre, vai ter mais uma pessoa na folha de pagamento, mais uma pessoa em determinado setor, etc. 

E quando demitimos, estamos subtraindo alguém, podemos usar o operador '-' para subtrair um objeto Funcionario do objeto Empresa, então no código, nesses casos, vamos ter que pagar direitos trabalhistas, outro funcionário vai ter que ficar com as funções que o demitido fazia, etc. 

Ou seja, fizemos uma sobrecarga de operadores '+' e '-', para terem diferente significados quando fazemos operações com esses objetos. Com a sobrecarga de operadores, você faz o que quiser com os objetos, os operadores farão o que você definir.

Há apenas 4 operadores que não podem ser sobrecarregados:

  1. .
  2. .*
  3. ::
  4. ?:
O restante você pode, e deve sobrecarregar, se fizer sentido, no seu projeto. Vamos aprender como fazer isso na prática?

Como fazer sobrecarga de operadores em C++

Vamos criar a classe Point, para representar um ponto no plano cartesiano. Ela recebe dois inteiros (coordenadas) e tem uma função que mostra essas coordenadas, veja a classe Point:

class Point
{
    private:
        int x, y;
    public:
        Point(int a, int b);
        void getPoint();
};

Porém, em álgebra vetorial, uma operação comum é a soma de vetores, que é basicamente somar as coordenadas de dois pontos.
Por exemplo: (1,2) + (2,3) = (1+2, 2+3) = (3,5)

Ou seja, a soma de dois pontos nada mais é que a soma das coordenadas, separadamente.

Então vamos lá, implementar isso com sobrecarga. O cabeçalho da sobrecarga é o mesmo de uma função. No nosso caso, fica:
  • Point operator+(Point p);
Ou seja, deve sempre retornar o tipo de dado da classe, que é Point. Depois escrevemos "operator+" para sobrecarregar o operador +, e por fim, colocamos o tipo de dado que vai ser somado, no caso, é outro objeto do tipo Point.

Nosso código fica:

#include <iostream>
using namespace std;

class Point
{
    public:
        int x, y;
        Point(int a, int b);
        void getPoint();
        Point operator+(Point p);
};

Point Point::operator+(Point p)
{
    x=x+p.x;
    y=y+p.y;

    return Point(x,y);
}

Point::Point(int a, int b)
{
    x=a;
    y=b;
}

void Point::getPoint()
{
    cout<<"("<<x<<","<<y<<")"<<endl;
}

int main()
{

    Point p1(1,2), p2(2,3);
    Point p3 = p1 + p2;
    p3.getPoint();

    return 0;
}

Uma maneira de ver essa operação é trocar:
p3 = p1 + p2;

Por:
p3 = p1.operador+(p2);

É como se a classe tivesse uma função chamada operador+, cujo parâmetro é outro objeto do tipo Point.

Exemplo de Sobrecarga de Operador

Vamos agora sobrecarregar o operador '='
Eu quero o seguinte: quando eu igualar um objeto do tipo Point com um inteiro, as coordenadas devem ser iguais a esse inteiro.

Ou seja, se eu fizer:
p=1, as coordenadas do objeto p devem ser (1,1)

Veja o código:

#include <iostream>
using namespace std;

class Point
{
    public:
        int x, y;
        Point(int a, int b);
        Point();
        void getPoint();
        Point operator+(Point p);
        void operator=(int n);
};
void Point::operator=(int n)
{
    x=n;
    y=n;
}
Point Point::operator+(Point p)
{
    x=x+p.x;
    y=y+p.y;

    return Point(x,y);
}

Point::Point()
{
    x=0;
    y=0;
}
Point::Point(int a, int b)
{
    x=a;
    y=b;
}

void Point::getPoint()
{
    cout<<"("<<x<<","<<y<<")"<<endl;
}

int main()
{

    Point p1(1,2), p2(2,3);
    Point p3 = p1 + p2;
    p3.getPoint();

    Point p4;
    p4=1;
    p4.getPoint();

    return 0;
}

Olha que curioso, igualamos o objeto 'p4', que é do tipo Point, com um número inteiro. Parece loucura, é como igualar carro com maçã. Mas o C++ permite essa 'loucura', você só precisa dar sentido a ela, e faz isso através da sobrecarga de operadores.

Sabe uma coisa mais louca, comparar se um objeto é maior que outro! 
?

Sobrecarga de Operador Relacional

Um vetor, no plano cartesiano, é definido por dois números (x,y)
Seu tamanho, chamado de módulo, é: d=sqrt(x² + y²) 
Ou seja, raiz quadrada de : x²+y²

Vamos criar a classe myVector para representar um vetor, e comparar se um vetor v1 é maior que um vetor v2, o código fica, ou seja, se v1 > v2

Porém, v1 e v2 são objetos da classe myVector, e não números, então não podemos fazer essa comparação diretamente, logo, teremos que fazer a sobrecarga do operador '>', para ele fazer outro tipo de operação:

#include <iostream>
#include <cmath>
using namespace std;

class myVector
{
    public:
        int x, y;
        myVector(int a, int b);
        bool operator>(myVector v);
};

bool myVector::operator>(myVector v)
{
    float d1, d2;
    d1=sqrt(x*x + y*y);
    d2=sqrt(v.x*v.x + v.y*v.y);

    if(d1>d2)
        return true;
    else
        return false;
}

myVector::myVector(int a, int b)
{
    x=a;
    y=b;
}

int main()
{
    myVector v1(6,8), v2(3,4);

    if(v1 > v2)
        cout<<"O vetor ("<<v1.x<<","<<v1.y<<") é maior que ("<<v2.x<<","<<v2.y<<")"<<endl;
    else
        cout<<"O vetor ("<<v1.x<<","<<v1.y<<") é menor ou igual a ("<<v2.x<<","<<v2.y<<")"<<endl;


    return 0;
}

No caso do operador '>', ele sempre retorna true ou false, por isso a sobrecarga retorna um bool.

Exercício de Sobrecarga de Operadores

Se você já fez o ensino médio, sabe o que são números complexos. São números do tipo:
x = a + bi

Onde 'a' é a parte real e 'b' a parte imaginária, pois é acompanhada do número imaginário 'i'.

Crie uma classe que representa um número complexo. Ela deve realizar a operação de soma e produto de números complexos.

Soma:
x = a + bi
y = c + di
s = x + y = (a+c) + (b+d)i

Produto:
p = x * y = (ac−bd)+(ad+bc)i

Postem nos comentários, as sobrecargas de vocês.

Nenhum comentário:

Postar um comentário