sencillos programacion poo polimorfismo herencia encapsulamiento ejemplos biología c++ polymorphism compile-time

c++ - programacion - polimorfismo php



¿Qué es el polimorfismo en tiempo de compilación y por qué solo se aplica a las funciones? (5)

¿Qué es el polimorfismo en tiempo de compilación y por qué solo se aplica a las funciones?


Con el polimorfismo de tiempo de compilación, generalmente se entiende el hecho de que puede tener varias funciones con el mismo nombre y el compilador elegirá en el momento de la compilación cuál usar de acuerdo con los argumentos:

void foo(int x); void foo(float y); //Somewhere else int x = 3; foo(x); //Will call first function float y = 2; foo(y); //Will call second function

La función foo se dice que está sobrecargada. Varios tipos de creación de instancias de plantilla también podrían denominarse polimorfismo de tiempo de compilación.


El polimorfismo de tiempo de compilación es un término que se refiere a la programación de plantillas de C ++. Por ejemplo, en tiempo de compilación usted determina el tipo real de un std :: vector por lo que contiene:

std::vector <int> vi; std::vector <std::string> vs;

No estoy seguro de por qué piensas que está limitado a funciones.



Lo que solo se aplica a las funciones es la deducción de parámetros de la plantilla. Si tengo una plantilla de función:

template <typename T> void foo(T &t);

Entonces puedo hacer int a = 0; foo(a); int a = 0; foo(a); , y esto será equivalente a int a = 0; foo<int>(a); int a = 0; foo<int>(a); . El compilador hace que me refiero a foo<int> . Al menos, resulta que debería usar foo<int> - si eso no es lo que quise decir entonces mala suerte para mí, y podría haber escrito foo<unsigned int>(a); o lo que sea.

Sin embargo, si tengo una plantilla de clase:

template <typename T> struct Foo { T &t; Foo(T &t) : t(t) {} T &getT() { return t; } };

Entonces no puedo hacer int a = 0; Foo(a).getT(); int a = 0; Foo(a).getT(); . Tengo que especificar Foo<int>(a) . El compilador no tiene permiso para trabajar, me refiero a Foo<int> .

Entonces, podría decirse que las plantillas de clase son "menos polimórficas" que las plantillas de función. El polimorfismo generalmente significa que no tiene que escribir código para hacer explícito el tipo de su objeto. Las plantillas de función permiten eso (en este caso particular), y las plantillas de clase no.

En cuanto a por qué este es el caso, la norma lo dice, no sé por qué. Los sospechosos habituales son (a) que es demasiado difícil de implementar, (b) no es útil, en opinión del comité estándar, o (c) crea alguna contradicción o ambigüedad en otra parte del lenguaje.

Pero todavía puedes hacer otros tipos de polimorfismo con clases:

template <typename T> struct Foo { T &t; Foo(T &t): t(t) {} void handleMany(int *ra, size_t s) { for (size_t i = 0; i < s; ++i) { t.handleOne(ra[i]); } } };

Esto generalmente también se denomina polimorfismo en tiempo de compilación, porque en lo que respecta al autor de la plantilla, t.handleOne podría ser cualquier cosa, y lo que sea se resolverá cuando sea necesario, "más adelante" en la compilación cuando Foo se ejemplifique.


Mucho tiempo atrás, el "polimorfismo de tiempo de compilación" significaba una sobrecarga de funciones. Se aplica solo a las funciones porque son todo lo que puedes sobrecargar.

En C ++ actual, las plantillas cambian eso. Neil Butterworth ya ha dado un ejemplo. Otro utiliza la especialización de plantillas. Por ejemplo:

#include <iostream> #include <string> template <class T> struct my_template { T foo; my_template() : foo(T()) {} }; template <> struct my_template<int> { enum { foo = 42 }; }; int main() { my_template<int> x; my_template<long> y; my_template<std::string> z; std::cout << x.foo << "/n"; std::cout << y.foo << "/n"; std::cout << "/"" << z.foo << "/""; return 0; }

Esto debería producir 42 , 0 y "" (una cadena vacía). Estamos obteniendo una estructura que actúa de manera diferente para cada tipo.

Aquí tenemos "polimorfismo de tiempo de compilación" de clases en lugar de funciones. Supongo que si quisiera discutir el punto, podría afirmar que esto es al menos parcialmente el resultado del constructor (una función) en al menos un caso, pero la versión especializada de my_template ni siquiera tiene un constructor.

Edit: En cuanto a por qué esto es el polimorfismo. Pongo "polimorfismo de tiempo de compilación" entre comillas por una razón: es algo diferente del polimorfismo normal. No obstante, estamos obteniendo un efecto similar al que esperaríamos de las funciones de sobrecarga:

int value(int x) { return 0; } long value(long x) { return 42; } std::cout << value(1); std::cout << value(1L);

La sobrecarga de funciones y la especialización están dando efectos similares. Estoy de acuerdo en que está abierto a la pregunta de si el "polimorfismo" se aplica a cualquiera de los dos, pero creo que se aplica igual de bien a uno que al otro.