Programación orientada a 2 objetos de inicio rápido en C ++

1. Tres permisos heredados

  • público: se puede acceder dentro y fuera de la clase.
  • protected: Acceso dentro de la clase y subclases, pero no fuera de la clase.
  • privado: solo se permite el acceso dentro de la clase, y no se puede acceder a ninguna subclase ni fuera de la clase.

2. Ajustar los permisos de herencia

Usando el nombre de clase using :: nombre de variable o método, puede controlar la autoridad de herencia de un solo miembro o método. El método de uso es el siguiente. Después de que Son hereda a Father, el permiso de la clave en la clase Father se cambia a público, y el mundo exterior también puede acceder a él; si se coloca en la clase privada de Son, entonces la clave se vuelve privada a Son y ya no puede ser utilizado por Son. Heredado por subclases.

class Father
{
	protected key;
};

class Son :public Father 
{
public:
	using Father::key;
}

3. Tipo de herencia

Hay 9 combinaciones de tipos de herencia. El principio es el principio de privilegio mínimo, como privado + protegido, luego el privilegio heredado es privado, el que sea menor.

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo anti-hotlinking. Se recomienda guardar la imagen y subirla directamente (img-IkbpsDgh-1611509116567) (C: \ Users \ 85114 \ AppData \ Roaming \ Typora \ typora-user-images \ image-20210121222038995.png)]

4. Herencia múltiple

Una clase puede heredar de varias clases base al mismo tiempo, como SofaBed hereda Sofa y Bed al mismo tiempo.

class SofaBed : public Sofa, public Bed
{

}

5. Herencia virtual

En el caso de herencia múltiple, varias clases base que pueden heredarse tienen los mismos miembros o métodos, y aparecerá ambigüedad en este momento. La herencia virtual puede resolver el problema de la ambigüedad y también resolver el problema del desperdicio de memoria (solo se conserva una copia del mismo miembro o método). La herencia virtual agregará un puntero de desplazamiento adicional de 4 bytes, que Baidu puede usar para heredar la distribución de memoria.

class SofaBed : virtual public Sofa, virtual public Bed
{

}

La secuencia de llamada del constructor y destructor de herencia virtual:

  1. El constructor de la clase base virtual se ejecuta primero y los constructores de múltiples clases base virtuales se construyen en el orden en que se heredan;
  2. Ejecute el constructor de la clase base y los constructores de varias clases base se construyen en el orden de herencia;
  3. El constructor del objeto miembro se ejecuta y los constructores de varios objetos miembro se construyen en el orden indicado;
  4. Ejecute el constructor de la clase derivada;
  5. La destrucción se realiza en el orden inverso de construcción;

6. La subclase pasa parámetros al constructor de la clase base.

Las subclases pueden pasar parámetros directamente al constructor de la clase base en el constructor, en forma de clase base (parámetros de entrada) y nombres de clase de miembro (parámetros de entrada). El orden de llamada de estos constructores no tiene nada que ver con el orden de escritura, pero según las primeras Las llamadas se realizan en el orden descrito en la sección 5.

class SofaBed : virtual public Sofa, virtual public Bed
{
private:
	Data data;	/* Data类 */
public:
   	/* SofaBed构造函数 */
    SofaBed(char *str1, char*str2, char *str3, char* str4) : Sofa(str1), Bed(str2), data(str3)
    {
        
    }
}

7, la realización del polimorfismo

El polimorfismo necesita depender de funciones virtuales para lograrlo.

#include <iostream>
using namespace std;

class Human {
private:
    int a;
public:
	virtual void eat(void) {cout<<"use hand to eat"<<endl;}
};

class English:public Human{
public:
	void eat(void){cout<<"use knife to eat"<<endl;}
};

class Chinese:public Human{
public:
	void eat(void){cout<<"use chopsticks to eat"<<endl;}
};

void eatTest(Human &human)
{
	human.eat();
}

int main(int argc, char **argv)
{
	Human h;
	English e;
	Chinese c;
	
	eatTest(h);
	eatTest(e);
	eatTest(c);
}

Los resultados de la ejecución son los siguientes:

use hand to eat
use knife to eat
use chopsticks to eat

Si elimina el atributo virtual del método eat en la clase Human, o cambia la función void eatTest (Human & human) a void eatTest (Human human), el resultado de la llamada es el siguiente, por lo que no se puede lograr el polimorfismo. El polimorfismo solo se puede lograr mediante punteros o referencias, y no es posible pasar valores directamente.

use hand to eat
use hand to eat
use hand to eat

8. El principio del polimorfismo

El programa se divide en enlace estático y enlace dinámico. Para el enlace estático, las funciones que se llamarán se determinan en tiempo de compilación. El caso de las funciones no virtuales está enlazado estáticamente; para el enlace dinámico, la función que se llamará se determina dinámicamente cuando el programa se está ejecutando, como las funciones virtuales. Caso. La unión estática es muy eficaz y la unión dinámica admite el polimorfismo.

Para el caso de una función virtual en una clase, habrá un puntero a una tabla de función virtual en la clase, y la función correspondiente en la tabla de función virtual se encontrará y se llamará a través del puntero al llamar, como se muestra a continuación. figura.

Inserte la descripción de la imagen aquí

Para el ejemplo anterior, sizeof (h) = sizeof (e) = sizeof (c) = 16. Porque la tabla de función virtual no solo contiene punteros de función virtual, sino también parte de la clase y la información de herencia .

9. Limitaciones del polimorfismo

  • Solo los miembros de una clase pueden declararse como funciones virtuales.
  • Las funciones de miembros estáticos no pueden ser funciones virtuales.
  • Las funciones en línea no pueden ser funciones virtuales.
  • El constructor no puede ser una función virtual.
  • Los destructores generalmente se declaran como funciones virtuales. Si el destructor no se declara como una función virtual, cuando se destruya la subclase, solo llamará al destructor de la clase principal, no al destructor de esta clase.
  • Las funciones sobrecargadas no pueden ser funciones virtuales.
  • Cuando los parámetros de la función son los mismos y el valor de retorno es un puntero o referencia de la clase, se permite declararlo como función virtual; si el valor de retorno es de otro tipo, no se permite configurarlo como función virtual. .

Supongo que te gusta

Origin blog.csdn.net/qq_27575841/article/details/113101405
Recomendado
Clasificación