Desenvolvimento - C/C++

Polimorfismo estático (C++)

Para explicar polimorfismo, nada como ver as coisas como elas eram.

por Wanderley Caloni Jr



Para explicar polimorfismo, nada como ver as coisas como elas eram. Se você fosse um programador C de vinte anos atrás e criasse as seguintes funções:

int soma(int x, int y);
double soma(double x, double y);

int main()
{
    int zi = soma(2, 3);
    double zd = soma(2.5, 3.4);
    return 0;
}

Imediatamente o compilador iria acusar os seguintes erros:

overload.c
overload.c(2) : warning C4028: formal parameter 1 different from declaration
overload.c(2) : warning C4028: formal parameter 2 different from declaration
overload.c(2) : error C2371: "soma" : redefinition; different basic types
 overload.c(1) : see declaration of "soma"

Isso acontece porque em C os identificadores são únicos por escopo. Esse é o motivo por que o seguinte código também está errado:

int main()
{
    int x = 0;
    int x = 1;
    return 0;
}

overload.c
overload.c(5) : error C2374: "x" : redefinition; multiple initialization
        overload.c(4) : see declaration of "x"

De volta aos anos 90, isso também está errado em C++. Até por uma questão de lógica: como o compilador pode saber a qual variável estamos nos referindo se usarmos o mesmo nome para duas delas?

Só que existe um truquezinho para impedir essa ambiguidade quando falamos de funções: os parâmetros que ela recebe.

int soma(int x, int y);
double soma(double x, double y);

int main()
{
    int zi = soma(2, 3); // dois tipos int: chamar soma(int, int)
    double zd = soma(2.5, 3.4); // dois tipos double: só pode ser soma(double, double)
    return 0;
}

C:\Tests>cl /c overload.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.6030 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

overload.cpp

C:\Tests>

Isso permitiu que em C++ fosse criada a sobrecarga estática, que é exatamente isso: chamar a função não apenas de acordo com seu nome, mas também de acordo com sua assinatura, ou seja, o número e o tipo dos parâmetros recebidos. Chamamos de sobrecarga estática porque isso é feito apenas pelo compilador, não pesando em nada durante a execução do programa.

Entre seus usos mais comuns estão os seguintes:

  • Ter funções com o mesmo nome mas que tratam de diferentes parâmetros;
    • soma(int, int);
    • soma(double, double);
    • Obs.: Isso ignora, é claro, as facilidades dos templates.
  • Versões novas da mesma função que recebem parâmetros adicionais;
    • export_data(void* buffer, int size);
    • export_data(void* buffer, int size, unsigned long options);
  • Mesmo nome de método para setar e obter o valor de uma propriedade;
    • Class::Property(int x); // setter
    • int x Class::Property() const; // getter
  • Bom, o que mais sua imaginação mandar =)

Artigo original: Caloni.com.br

Wanderley Caloni Jr

Wanderley Caloni Jr