C++ orientado a objetos (parte 2)

 El contenido general de la explicación es lista de inicialización, palabra clave explícita, miembros estáticos (estáticos)


Tabla de contenido

Lista de inicialización y asignación de constructor de funciones

asignación de constructor de funciones

lista de inicialización

Orden de inicialización utilizando la lista de inicializadores

Ventajas de usar listas de inicialización

palabra clave explícita

miembro estático (estático)

concepto


Lista de inicialización y asignación de constructor de funciones

asignación de constructor de funciones

Al crear un objeto, el compilador le dará a cada variable miembro en el objeto un valor inicial apropiado llamando al constructor:

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
    {
        _X = X;
        _Y = Y;
        _Z = Z;
    }
private:
    int _X;
    int _Y;
    int _Z;
};

Nota: La asignación del constructor de funciones anterior se puede asignar varias veces, y la lista de inicialización de la que hablaremos a continuación

lista de inicialización

1. Cada variable miembro solo puede aparecer una vez en la lista de inicialización  porque la inicialización solo se puede realizar una vez , por lo que la misma variable miembro no puede aparecer varias veces en la lista de inicialización .

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
        :_X(X)
        ,_Y(Y)
        ,_Z(Z)
    {}
private:
    int _X;
    int _Y;
    int _Z;
};

2. La clase contiene los siguientes miembros, que deben colocarse en la lista de inicialización para la inicialización:

1. Variables de miembro de referencia A las variables  de tipo de referencia se les debe dar un valor inicial cuando se definen, por lo que las variables de miembro de referencia deben inicializarse mediante una lista de inicialización.

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
        :_X(X)
        ,_Y(Y)
        ,_Z(Z)
    {}
private:
​
    int& _b = 0;// 创建时就初始化
};

2. La variable miembro const  modificada por const también debe recibir un valor inicial cuando se define, y también debe inicializarse utilizando la lista de inicialización.

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
        :_X(X)
        ,_Y(Y)
        ,_Z(Z)
    {}
private:
    
    const int a = 10;//correct 创建时就初始化
};
 
 

3. Miembros de tipo personalizado (esta clase no tiene un constructor predeterminado)  Si una clase no tiene un constructor predeterminado , entonces debemos pasar parámetros para inicializarla al crear una instancia del objeto de clase , por lo que debe inicializarse una instancia de un objeto de clase sin un constructor predeterminado. utilizando una lista de inicializadores .

class B
{
    public:
    // 没有默认构造
    Date(int Big)
      :_Big(Big);
    {}
private:
    int _Big;
};
​
class A
{
    public:
    // 构造函数
    Date(int A = 0)
        :_Big(A)
    {}
private:
    int _A;
    B _Big;
};

 Aquí nuevamente, el constructor predeterminado se refiere a un constructor que se puede llamar sin pasar parámetros:

 1. No escribimos, el compilador genera automáticamente el constructor. 2. Sin constructor de parámetros. 3. Todos los constructores predeterminados.

Orden de inicialización utilizando la lista de inicializadores

Por ejemplo:

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
        :_X(X)
        ,_Y(Y)
        ,_Z(Z)
    {}
private:
    //初始化列表的初始化顺序
    int _X;//1
    int _Y;//2
    int _Z;//3
};

Nota: El orden de inicialización de la lista de inicialización se inicializa de arriba a abajo según su definición en privado

Ventajas de usar listas de inicialización

 Debido a que la lista de inicialización es en realidad el lugar donde se definen las variables miembro del objeto cuando crea una instancia de un objeto, ya sea que use la lista de inicialización o no, pasará por dicho proceso (las variables miembro deben definirse). Estrictamente hablando: 1. Para los tipos incorporados, en realidad no hay diferencia entre usar la lista de inicialización e inicializar en el cuerpo del constructor. La diferencia es similar a la siguiente

1. Para los tipos incorporados, prácticamente no hay diferencia entre usar la lista de inicialización e inicializar en el cuerpo del constructor.

2. Para tipos personalizados, usar la lista de inicialización puede mejorar la eficiencia del código

palabra clave explícita

Después de usar esta palabra clave explícita para modificar el constructor , no se puede usar la conversión implícita del constructor de un solo argumento .

class A
{
public:
    // 构造函数
    Date(int X = 0)
    _X = X;
    {}
    Print()
    {
        cout<< _X <<endl;
    }
private:
    int _X;
};
int main()
{
    A a1 = 100;
    return 0;
}
 
 

Entonces, en los primeros compiladores, cuando el compilador encuentra el código A a1 = 100, primero construye un objeto temporal y luego usa el objeto temporal para copiar y construir a1; pero el compilador actual ha sido optimizado, cuando encuentra Cuando el código A a1 = 100, esto se llama conversión de tipo implícita .

miembro estático (estático)

concepto

 Los miembros de clase declarados como estáticos se denominan miembros estáticos de la clase. Las variables miembro modificadas con estática se denominan variables miembro estáticas; las funciones miembro modificadas con estática se denominan funciones miembro estáticas. Las variables miembro estáticas deben inicializarse fuera de la clase , está en el área estática (en el modelo de memoria).

Los miembros estáticos son compartidos por todos los miembros de la clase y no pertenecen a una clase específica.

class A
{
private:
    static int _a;
};
int main()
{
    cout << sizeof(A) << endl;
    return 0;
}

Da como resultado un tamaño de 1 porque es un miembro estático _a (en el área estática), que pertenece a toda la clase . Entonces, al calcular el tamaño de una clase o el tamaño de un objeto de clase, los miembros estáticos no se cuentan.

Las variables miembro estáticas deben definirse e inicializarse fuera de la clase

class A
{
private:
    static int _a;
};
int main()
{
    cout << sizeof(A) << endl;
    return 0;
}
int A::_A = 0;//定义初始化

Formas de acceder a variables miembro estáticas

class A
{
public:
    static int _a; //静态,属于整个类
};
// 静态成员变量的定义初始化
int A::_a = 0;
int main()
{
    Test test;
    cout << A._a << endl; //1.通过类对象突破类域进行访问
    cout << A()._a << endl; //3.通过匿名对象突破类域进行访问
    cout << A::_a << endl; //2.通过类名突破类域进行访问
    return 0;
}
  • El primero es: acceder a través del objeto de clase para atravesar el dominio de clase

  • El segundo es: acceder a través de objetos anónimos para atravesar el dominio de la clase.

  • El tercero es: acceda a través del nombre de la clase para atravesar el dominio de la clase.

Las funciones miembro estáticas no tienen este puntero

class A
{
public:
    static void Fun()
    {
        cout << _a << endl; //不能访问非静态成员
        cout << _b << endl; //可以
    }
private:
    int _a; //非静态成员
    static int _b; //静态成员
}

Nota: Los miembros estáticos, al igual que los miembros ordinarios de una clase, también tienen tres niveles de acceso: público, privado y protegido. 

Nota:

1. ¿Puede una función miembro estática llamar a una función miembro no estática?

  • No poder. Debido a que el primer parámetro formal de una función miembro no estática tiene como valor predeterminado el puntero this y no existe un puntero this en una función miembro estática, una función miembro estática no puede llamar a una función miembro no estática.

2. ¿Puede una función miembro no estática llamar a una función miembro estática?

  • Poder. Debido a que tanto las funciones miembro estáticas como las funciones miembro no estáticas están en la clase, no están restringidas por el calificador de acceso en la clase.

Supongo que te gusta

Origin blog.csdn.net/qq_45591898/article/details/130755722
Recomendado
Clasificación