Dominando Sobrecarga de Operadores em C++: Exemplos Práticos e Boas Práticas
Sobrecarga de Operadores em C++
Neste tutorial, aprenderemos sobre sobrecarga de operadores com a ajuda de exemplos.
Em C++, podemos mudar a forma como operadores funcionam para tipos definidos pelo usuário como objetos e estruturas. Isso é conhecido como sobrecarga de operadores. Por exemplo,
Suponha que criamos três objetos c1, c2 e resultado de uma classe chamada Complexo que representa números complexos.
Como a sobrecarga de operadores nos permite mudar como operadores funcionam, podemos redefinir como o operador + funciona e usá-lo para somar os números complexos de c1 e c2 escrevendo o seguinte código:
resultado = c1 + c2;
em vez de algo como
resultado = c1.adicionarNumeros(c2);
Isso torna nosso código intuitivo e fácil de entender.
Nota: Não podemos usar sobrecarga de operadores para tipos de dados fundamentais como int, float, char e assim por diante.
Sintaxe para Sobrecarga de Operadores em C++
Para sobrecarregar um operador, usamos uma função especial operator. Definimos a função dentro da classe ou estrutura cujos objetos/variáveis queremos que o operador sobrecarregado funcione.
class nomeClasse { ... .. ... public tipoRetorno operator simbolo (argumentos) { ... .. ... } ... .. ... };
Aqui,
tipoRetornoé o tipo de retorno da função.operatoré uma palavra-chave.simboloé o operador que queremos sobrecarregar. Como:+,<,-,++, etc.argumentossão os argumentos passados para a função.
Sobrecarga de Operadores Unários
Operadores unários operam em apenas um operando. O operador de incremento ++ e decremento -- são exemplos de operadores unários.
Exemplo 1: Sobrecarga do Operador ++ (Operador Unário)
// Sobrecarrega ++ quando usado como prefixo #include <iostream> using namespace std; class Contador { private: int valor; public: // Construtor para inicializar contador com 5 Contador() : valor(5) {} // Sobrecarrega ++ quando usado como prefixo void operator ++ () { ++valor; } void exibir() { cout << "Contador: " << valor << endl; } }; int main() { Contador contador1; // Chama a função "void operator ++ ()" ++contador1; contador1.exibir(); return 0; }
Saída
Contador: 6
Aqui, quando usamos ++contador1;, a função void operator ++ () é chamada. Isso aumenta o atributo valor para o objeto contador1 em 1.
Nota: Quando sobrecarregamos operadores, podemos usá-los para funcionar de qualquer forma que quisermos. Por exemplo, poderíamos ter usado ++ para aumentar valor em 100.
No entanto, isso torna nosso código confuso e difícil de entender. É nosso trabalho como programadores usar sobrecarga de operadores de forma adequada, consistente e intuitiva.
O exemplo acima funciona apenas quando ++ é usado como prefixo. Para fazer ++ funcionar como pós-fixo usamos esta sintaxe.
void operator ++ (int) { // código }
Observe o int dentro dos parênteses. É a sintaxe usada para usar operadores unários como pós-fixo; não é um parâmetro de função.
Exemplo 2: Sobrecarga do Operador ++ (Operador Unário) como Prefixo e Pós-fixo
// Sobrecarrega ++ quando usado como prefixo e pós-fixo #include <iostream> using namespace std; class Contador { private: int valor; public: // Construtor para inicializar contador com 5 Contador() : valor(5) {} // Sobrecarrega ++ quando usado como prefixo void operator ++ () { ++valor; } // Sobrecarrega ++ quando usado como pós-fixo void operator ++ (int) { valor++; } void exibir() { cout << "Contador: " << valor << endl; } }; int main() { Contador contador1; // Chama a função "void operator ++ (int)" contador1++; contador1.exibir(); // Chama a função "void operator ++ ()" ++contador1; contador1.exibir(); return 0; }
Saída
Contador: 6 Contador: 7
O Exemplo 2 funciona quando ++ é usado tanto como prefixo quanto pós-fixo. No entanto, não funciona se tentarmos fazer algo assim:
Contador contador1, resultado; // Erro resultado = ++contador1;
Isso ocorre porque o tipo de retorno da nossa função operador é void. Podemos resolver esse problema tornando Contador o tipo de retorno da função operador.
// retorna Contador quando ++ usado como prefixo Contador operator ++ () { // código } // retorna Contador quando ++ usado como pós-fixo Contador operator ++ (int) { // código }
Exemplo 3: Valor de Retorno da Função Operador (Operador ++)
#include <iostream> using namespace std; class Contador { private: int valor; public : // Construtor para inicializar contador com 5 Contador() : valor(5) {} // Sobrecarrega ++ quando usado como prefixo Contador operator ++ () { Contador temp; // Aqui, valor é o atributo valor do objeto chamador temp.valor = ++valor; return temp; } // Sobrecarrega ++ quando usado como pós-fixo Contador operator ++ (int) { Contador temp; // Aqui, valor é o atributo valor do objeto chamador temp.valor = valor++; return temp; } void exibir() { cout << "Contador: " << valor << endl; } }; int main() { Contador contador1, resultado; // Chama a função "Contador operator ++ ()" resultado = ++contador1; resultado.exibir(); // Chama a função "Contador operator ++ (int)" resultado = contador1++; resultado.exibir(); return 0; }
Saída
Contador: 6 Contador: 6
Aqui, usamos o seguinte código para sobrecarga do operador prefixo:
// Sobrecarrega ++ quando usado como prefixo Contador operator ++ () { Contador temp; // Aqui, valor é o atributo valor do objeto chamador temp.valor = ++valor; return temp; }
O código para sobrecarga do operador pós-fixo também é similar. Observe que criamos um objeto temp e retornamos seu valor para a função operador.
Também observe o código
temp.valor = ++valor;
A variável valor pertence ao objeto contador1 em main() porque contador1 está chamando a função, enquanto temp.valor pertence ao objeto temp.
Sobrecarga de Operadores Binários
Operadores binários funcionam em dois operandos. Por exemplo,
resultado = num + 9;
Aqui, + é um operador binário que funciona nos operandos num e 9.
Quando sobrecarregamos o operador binário para tipos definidos pelo usuário usando o código:
obj3 = obj1 + obj2;
A função operador é chamada usando o objeto obj1 e obj2 é passado como argumento para a função.
Exemplo 4: Sobrecarga de Operador Binário em C++
// Programa C++ para sobrecarregar o operador binário + // Este programa soma dois números complexos #include <iostream> using namespace std; class Complexo { private: float real; float imag; public: // Construtor para inicializar real e imag com 0 Complexo() : real(0), imag(0) {} void entrada() { cout << "Digite partes real e imaginária respectivamente: "; cin >> real; cin >> imag; } // Sobrecarrega o operador + Complexo operator + (const Complexo& obj) { Complexo temp; temp.real = real + obj.real; temp.imag = imag + obj.imag; return temp; } void saida() { if (imag < 0) cout << "Número complexo de saída: " << real << imag << "i"; else cout << "Número complexo de saída: " << real << "+" << imag << "i"; } }; int main() { Complexo complexo1, complexo2, resultado; cout << "Digite o primeiro número complexo:\n"; complexo1.entrada(); cout << "Digite o segundo número complexo:\n"; complexo2.entrada(); // complexo1 chama a função operador // complexo2 é passado como argumento para a função resultado = complexo1 + complexo2; resultado.saida(); return 0; }
Saída
Digite o primeiro número complexo: Digite partes real e imaginária respectivamente: 9 5 Digite o segundo número complexo: Digite partes real e imaginária respectivamente: 7 6 Número complexo de saída: 16+11i
Neste programa, a função operador é:
Complexo operator + (const Complexo& obj) { // código }
Em vez disso, também poderíamos ter escrito esta função como:
Complexo operator + (Complexo obj) { // código }
No entanto,
- usar
&torna nosso código eficiente referenciando o objeto complexo2 em vez de criar um objeto duplicado dentro da função operador. - usar
consté considerado uma boa prática porque impede a função operador de modificar complexo2.

Coisas para Lembrar na Sobrecarga de Operadores em C++
- Dois operadores
=e&já são sobrecarregados por padrão em C++. Por exemplo, para copiar objetos da mesma classe, podemos usar diretamente o operador=. Não precisamos criar uma função operador. - A sobrecarga de operadores não pode mudar a precedência e associatividade dos operadores. No entanto, se quisermos mudar a ordem de avaliação, parênteses devem ser usados.
- Existem 4 operadores que não podem ser sobrecarregados em C++. Eles são:
::(resolução de escopo).(seleção de membro).*(seleção de membro através de ponteiro para função)?:(operador ternário)
Visite estas páginas para aprender mais sobre:
- Como sobrecarregar operador de incremento da maneira correta?
- Como sobrecarregar operador binário - para subtrair números complexos?
Linguagem C
- Operadores em C# – Guia Completo dos Operadores em C#
- Operador Ternário em C#: Guia Conciso para Expressões Condicionais
- Dominando Sobrecarga de Métodos em C#: Conceitos, Exemplos e Boas Práticas
- Dominando Sobrecarga de Construtores em C#
- Dominando Operadores em C++: Guia Completo com Exemplos Práticos
- Comentários em C++: Boas Práticas para Código Legível e Manutenível
- Dominando Templates de Classe em C++: Um Guia Prático
- Dominando Sobrecarga de Operadores em Python: Guia Prático
- Operadores em C++ Explicados: Tipos, Exemplos e Programas Práticos
- Sobrecarga de Operadores em C++: Guia Prático com Exemplos de Código