Eficaz C ++ Artículo 30: Aplicación de la (conocimiento profundo de las entradas y salidas de inlining)

A, ventajas en línea y desventajas

ventaja

  • La eliminación de la llamada función de coste

defecto

  • Como una función del cuerpo en vez de llamadas a funciones, por lo que un objetivo de gran aumento
  • En la maquina de memoria prioritarios, el uso excesivo de volumen en línea demasiado hará que el programa
  • Incluso con la memoria virtual, hinchazón de código en línea causado también causa el comportamiento de paginación adicional, la reducción del conjunto de instrucciones del dispositivo de memoria caché, y la consiguiente pérdida de eficiencia

En segundo lugar, la línea explícita en línea implícita

  • en línea es sólo una solicitud para el compilador, no obligatoria de comandos
  • Ahora sólo dentro de la clase implícita en línea . Por ejemplo:
class Person {
public:
    int age()const { return theAge; } //隐式内联(编译器自动申请)
private:
    int theAge;
};
  • También podemos señalar explícitamente por palabra inline una función como una función en línea. Por ejemplo:
template<typename T>
inline const T& std::max(const T& a, const T& b)
{
    return a < b ? b : a;
}

En tercer lugar, la línea de plantilla

  • funciones en línea se colocan generalmente en los archivos de cabecera , porque la mayor parte del entorno de compilación inlining en el proceso de compilación, es necesario saber las miradas función en línea como. inlining compilador de la conducta en la mayoría de los programas de C ++ (pero hay algunos casos inlining se realiza en el período de ejecución de enlace)
  • plantilla por lo general se coloca en la cabecera de la plantilla , por lo que una vez utilizado, el compilador para crear una instancia, pero también necesita saber lo que parece
  • plantilla de hormigón y inlining tiene nada que ver:
    • Si se escribe una función de la aplicación específica de la plantilla que debería ser inline, entonces será declarado como plantilla en línea
    • Si se escribe código inline hay razón alguna para que, entonces no va a ser declarado como una línea plantilla (como el código pueden producir hinchazón)

En cuarto lugar, el caso de rechazado por el compilador de línea

  • Incluso si se declara una función en línea, pero en algunos casos el compilador se negará a funcionar como inline. Por ejemplo:
    • funciones demasiado complicado : por ejemplo, con o bucle recursivo
    • Las llamadas a funciones virtuales (a menos que sea la más prosaica): Debido a que los medios virtuales "de espera" hasta que la carrera fue determinar qué función a la llamada, pero los medios en línea que se puede determinar en la llamada de compilación del cuerpo de la función. Así será rechazada función virtual entrega del compilador para estar en línea
  • resumen:
    • Una función aparentemente en línea, o una función explícita mediante declaración en línea, al final no es una función en línea, dependiendo de su entorno y el compilador
    • La mayoría de los compiladores proporcionan un nivel de diagnóstico: Si no puede inline una función de, dará una advertencia

El constructor y el destructor no son a veces el inlining

  • Ahora allí siguiendo una jerarquía de herencia de clases
class Base{
public:
    //...
private:
    std::string bm1, bm2;
};

class Derived :public Base {
public:
    Derived() {}   //构造函数为空
private:
    std::string dm1, dm2, dm3;
};
  • El constructor por encima Derivado está vacío, entonces se podría pensar cuando inlining el constructor de Derivados, pero en realidad no es el caso
  • Sabemos que el C ++ porción constructor y el destructor siguientes reglas:
    • Si la clase se deriva, a continuación, la necesidad de realizar su propia configuración antes de que el constructor de la clase base y destructor similares
    • Si no inicializar los miembros de datos de la clase en el constructor, el compilador hará automáticamente los miembros de datos iniciales de una clase (el código de inicialización compilador que agregó)
  • El ejemplo anterior aunque constructor Derivado está vacío, pero hay tres miembros de datos, hay dos miembros de datos de clase base. El siguiente es pseudo-código, el compilador inicializa automáticamente los miembros de datos:
//伪代码
Derived::Derived() 
{
    //下面是编译器为空的Derived构造函数添加的代码
    Base::Base(); //初始化BaSE部分

    try {
        dm1.std::string::string();
    }
    catch (...) {
        Base::~Base();
        throw;
    }

    try {
        dm2.std::string::string();
    }
    catch (...) {
        dm1.std::string::~string();
        Base::~Base();
        throw;
    }

    try {
        dm3.std::string::string();
    }
    catch (...) {
        dm2.std::string::~string();
        dm1.std::string::~string();
        Base::~Base();
        throw;
    }
}

V. Resumen

  • La mayoría de procesos en línea se limita a pequeñas, con frecuencia llamada la función del cuerpo. Esto permite futuro depuración y actualizaciones binarias más fácil, sino que también permite que los problemas potenciales para minimizar la hinchazón de código, la oportunidad de maximizar la aceleración del programa
  • No, para las plantillas de función aparecen en el archivo de cabecera, que serán declarados como privados
Liberadas 1504 artículos originales · ganado elogios 1063 · Vistas de 430.000 +

Supongo que te gusta

Origin blog.csdn.net/qq_41453285/article/details/104711068
Recomendado
Clasificación