Explicar el mecanismo de implementación del polimorfismo en detalle.

Tres manifestaciones de polimorfismo.

Polimorfismo: Es una variedad de formas.Cuando se completa un determinado comportamiento, la terminación de diferentes objetos producirá diferentes resultados. La manifestación dentro de la función es la interfaz de la misma función, pero aparecen resultados diferentes.
Hay tres formas de polimorfismo:
1. Polimorfismo estático, es decir, la llamada a la función se determina en la etapa de compilación,
2. Polimorfismo dinámico, la llamada a la función se determina durante la etapa de ejecución.
3. Macro polimorfismo, la llamada a la función se determina en la etapa de precompilación.
En el estado predeterminado, el valor predeterminado es generalmente polimorfismo dinámico. Para lograr el polimorfismo dinámico, se necesitan funciones virtuales que brinden soporte;

El mecanismo de realización del polimorfismo.

Debido a que el polimorfismo estático solo determina la llamada a la función en la fase de tiempo de ejecución, necesitamos obtener la dirección de entrada de la función en la fase de tiempo de ejecución para lograr el polimorfismo. Sin embargo, el símbolo de función y la dirección de entrada se determinan durante la etapa de compilación del programa. Por lo tanto, las funciones ordinarias no pueden lograr un polimorfismo dinámico. Por lo tanto, hemos introducido la palabra clave virtual, cuya función es almacenar una copia de la dirección de entrada de la función en la tabla de funciones virtuales (vftable) en el segmento de datos .rodata. Luego, al cargar instrucciones y datos en la fase de ejecución del programa, la dirección de entrada de la función también se puede cargar en la memoria. Hay tres piezas de información almacenadas en la tabla de funciones virtuales (vftable):

1. Información de RTTI (identificación de tipo en tiempo de ejecución), en términos simples, la información de RTTI se utiliza para determinar la información de tipo en tiempo de ejecución.
2. Desplazamiento: se refiere al desplazamiento del puntero de la tabla de funciones virtuales equivalente al alcance general, generalmente porque el puntero de la función virtual tiene una prioridad más alta , vfptr ocupa un valor bajo en el diseño de memoria de un objeto, generalmente 0, y el desplazamiento es la posición de 0-vfptr, por lo que en la mayoría de los casos el desplazamiento es 0;
3. La dirección de entrada de la función: Este lugar es la dirección de entrada de la función virtual, que es el alma del polimorfismo. En el análisis posterior de la función, se puede encontrar la dirección de entrada de la función, de modo que se puede realizar la misma función, pero el resultado de la ejecución es diferente.

Dado que el objeto y la tabla de función virtual están en una relación compartida, se generará un vfptr dentro del objeto generado para apuntar a una tabla de función virtual (vftable). Entonces, cuando ocurre el polimorfismo, el tamaño de () del objeto será cuatro bytes más grande que el original.

Realice el diseño del espacio de memoria polimórfica

Como se mencionó anteriormente, de acuerdo con la descripción, después de la aparición del polimorfismo, habrá un puntero vfptr más dentro del objeto para apuntar a vftable, y la prioridad de vfptr será mayor, por lo que el diseño de memoria de un objeto se puede obtener mediante ejemplo de la siguiente manera:
Código:

class Base
{
    
    
public:
	void Base(int ma):_ma(ma)
	{
    
    }
	virtual void show()
	{
    
    
	std::cout<<"base::show ma="<<ma<<std::endl;
	}
private:
	int _ma;
}
class derive:public Base
{
    
    
public:
	void derive(int mb):_mb(mb),Base(mb)
	{
    
    }
	virtual void show()    
	{
    
    
		std::cout<<"derive show mb="<<mb<<std::endl;
	}
private:
	int mb; 
}
int main()
{
    
    
	Base a;
	derive b;
	return 0;
}

De acuerdo con el código anterior, encontramos que la clase base es polimórfica y la clase derivada también es polimórfica. Entonces podemos usar la herramienta para encontrar el diseño del espacio de la Base como: Inserte la descripción de la imagen aquí
Esto verifica aún más el punto anterior: ** Cuando ocurre el polimorfismo, habrá un vfptr adicional dentro del objeto; ** De manera similar, podemos usar la herramienta para encontrar La estructura de la tabla de funciones virtuales es:
Inserte la descripción de la imagen aquí
Estas tres líneas representan respectivamente la información RTTI, el desplazamiento y la dirección de entrada de la función.
Nota: Después de la herencia, la tabla de función virtual en la clase derivada cambiará:
la estructura de la tabla de función virtual de la clase base:
Inserte la descripción de la imagen aquí
la tabla de función virtual de la clase derivada Inserte la descripción de la imagen aquí
cuando no ocurre herencia : cuando ocurre la relación de herencia, el mismo nombre y el mismo parámetro en la clase derivada La función virtual anulará la función virtual con el mismo nombre y el mismo parámetro en la clase base :Inserte la descripción de la imagen aquí

Referencia y apuntamiento mutuo entre la clase base y la clase derivada

Para la clase base, un puntero de clase base definido puede apuntar o hacer referencia a objetos de clase derivada. Para un puntero de clase derivada, no puede apuntar a un objeto de clase base. Esto se debe a que cuando se accede al puntero, el puntero de la clase base puede acceder a toda la información que el puntero de la clase base desea obtener y el puntero del objeto de la clase derivada no puede garantizar que el objeto de la clase base contenga la interfaz o variable que necesita. Inserte la descripción de la imagen aquí
Por lo tanto, la tabla de funciones virtuales de la clase derivada finalmente se realiza mediante dos partes: 1. La tabla de funciones virtuales de la clase base 2. La tabla de funciones virtuales de la clase derivada en sí.
Además, cuando se produce la herencia, el diseño de la memoria también cambiará: Inserte la descripción de la imagen aquí
Nota: El puntero de función virtual se fusionará hacia adentro, es decir, se fusionará de la clase derivada a la clase base;

para resumir

El proceso de polimorfismo dinámico es el siguiente:
Inserte la descripción de la imagen aquí
primero genere la tabla de función virtual, y luego dibuje el vfptr en el diseño de memoria para apuntar a la tabla de función virtual, y luego use el puntero de objeto de clase base pb para apuntar al objeto de clase derivada. Para realizar el acceso del puntero de clase base a la función de clase derivada Derive :: show.

Supongo que te gusta

Origin blog.csdn.net/ALITAAAA/article/details/109450267
Recomendado
Clasificación