2011-10-24 11 views
5

que tienen una clase simple:¿Tiene un getter cero costo?

class A { 
    public: 
    int get() const; 

    private: 
    void do_something(); 
    int value; 
} 

int A::get() const { 
    return value; 
} 

La función getter es sencilla y directa. Los Getters deben usarlos, así que en do_something debo usar get() para acceder al value. Mi pregunta es: ¿el compilador optimizará el getter, por lo que será equivalente a acceder a los datos directamente? O aún obtendré rendimiento si tengo acceso directo (¿qué implicaría un peor diseño)?

A::do_something() 
{ 
    x = get(); 
    // or... 
    x = value; 
} 
+0

La verdadera pregunta, por supuesto, es: * ¿Importa *? Porque si no lo hace, ¿a quién le importa? Y si lo hace, solo usted puede verificar si su compilador en particular realiza la optimización. –

Respuesta

7

Cuando el método no es virtual, los compiladores pueden optimizarlo. Los buenos compiladores (con optimización de tiempo de enlace) pueden optimizar incluso si el método no es inline y se define en un archivo .cpp separado. No tan buenos solo pueden hacer eso si se declara dentro de la definición de la clase, o en el archivo de encabezado con la palabra clave inline. Para los métodos virtuales, depende, pero probablemente no.

+0

bueno por mencionar algo 'virtual'. – iammilind

+3

Para funciones virtuales, depende de si el compilador conoce el tipo dinámico o no.Si bien el uso más frecuente de las funciones virtuales resulta en contextos en los que no puede, hay excepciones, y conozco al menos un modismo que depende del compilador que delimita las funciones virtuales. –

3

Es casi seguro que el compilador alinee un getter tan trivial, si tiene acceso a la definición.

+0

¿Será getter en línea sin la palabra clave 'inline' al definirlo fuera de la clase? – ks1322

+0

@ ks1322: la definición en clase de funciones miembro se declara implícitamente como 'en línea'. – Nawaz

+0

@Nawaz, estoy preguntando ¿estará incluido en este caso particular (ninguna palabra clave 'inline', función de miembro está definida ** fuera ** de la clase)? – ks1322

2

Si el captador se define como una función en línea (ya sea implícitamente definiéndolo dentro de la clase, o explícitamente con la palabra clave inline), el compilador generalmente lo alineará y no habrá sobrecarga al llamarlo.

Sin embargo, es común que las compilaciones de depuración inhabiliten la alineación, lo cual es perfectamente válido ya que los compiladores no necesitan alinear nada.

1

Bueno, usar get suele ser un mejor diseño porque oculta la lógica real involucrada en obtener el valor (hoy es un campo, mañana puede requerir lógica más compleja). En cuanto al rendimiento, aunque el acceso al valor en sí siempre será al menos tan rápido como usar get, el compilador probablemente incorporará la llamada de todos modos.

1

En primer lugar, no sería capaz de manipular el valor dentro de su objeto si no devuelve una referencia en lugar del valor:

int& get(); 

Ahora se devuelve una referencia y pueden ser alterados. Pero en mi humilde opinión esto no es bastante limpio, también debe definir una incubadora y lo utilizan para escribir de nuevo el valor modificado:

int get() const; 
void set(int); 

... 
A::do_something() 
{ 
    x = get(); 
    set(value); 
} 

El desempeño de la incubadora depende de su compilador. La mayoría de los compiladores modernos pueden alinear getters/setters simples, por lo que no debería haber ninguna pérdida de rendimiento.

Cuestiones relacionadas