Pregunta

En concreto, me pregunto cuál de ellos debería escribir:

{
    shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock();
    if (subMenu)
        subMenu->setVisible(false);
}

o

{
    if (items[j].subMenu.lock())
        items[j].subMenu.lock()->setVisible(false);
}

No tengo obligación de seguir las directrices de estilo. Después de la optimización, no creo que sea elección hace la diferencia en el rendimiento. Lo que generalmente es el estilo preferido y por qué?

EDIT: el tipo de elementos [j] es .subMenu impulso :: weak_ptr. cerradura () crea un shared_ptr fuera de él. En realidad, hay una diferencia ambigua en las dos versiones anteriores, con respecto a la duración de la shared_ptr temporal, por lo envolví mis dos ejemplos en las llaves {} para resolver la ambigüedad allí.

¿Fue útil?

Solución

Un método alternativo:

if(shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock()) {
    subMenu->setVisible(false);
}
//subMenu is no longer in scope

Asumo subMenu es un weak_ptr, en cuyo caso el segundo método crea dos temporales, lo que podría o no podría ser un problema. Y su primer método agrega una variable a un ámbito más amplio de lo que necesita. En lo personal, trato de asignaciones dentro de Evita declaraciones if, pero este es uno de los pocos casos en los que siento que es más útil que las alternativas.

Otros consejos

este caso en particular , que realmente debería utilizar la versión con la variable temporal. La razón no es el rendimiento, pero la corrección - básicamente, no se garantiza que las dos llamadas x.lock() devuelven el mismo valor (por ejemplo, si otro hilo libera la última referencia fuerte en el objeto justo entre las dos llamadas.). Con la celebración de la fuerte referencia en la variable temporal, se asegura que no va a desaparecer.

Aparte de eso:

  • los compiladores por lo general no se puede optimizar a cabo las llamadas a funciones, a menos que sean demostrablemente libre de efectos secundarios (esto es difícil de hacer, pero atribuye la ayuda de mayo) o inline. En este caso, la llamada tiene efectos secundarios.

  • usando los temporales puede conducir a programas más corto, más legibles y más fácil de mantener (por ejemplo. En caso de error, a solucionarlo en un solo lugar)

Te pienso en lo correcto acerca de una u otra opción de ser no es diferente después de la optimización.

En lo personal, me gustaría declarar una nueva variable si se hace que el código sea más legible, como cuando se está encadenando llamadas, o poner las llamadas a funciones dentro de llamadas a funciones. Mientras que es fácil de mantener y el código consigue el mismo efecto sin diferencia de velocidad, todo se reduce a un código legible.

Editar

mmyers compraron un comentario bueno. Sí, tener cuidado con llamar lock() dos veces, en lugar de sólo una vez. Ellos tendrán diferentes efectos en función de su aplicación.

La elección es esencialmente depende de usted, pero lo básico que debe tener en cuenta es el mantenimiento.

Cuando el valor de retorno es otra cosa que un valor lógico, asignarlo a una variable intermedia a menudo puede simplificar la depuración. Por ejemplo, si paso por el siguiente:

if( fn() > 0 ) ...

todo lo que se sabe después de que el hecho era que la función devuelve un valor, ya sea menor que cero o cero o más. Incluso si el valor de retorno no son correctos, el código puede aparecer al trabajo. Asignarlo a una variable que puede ser inspeccionado en su depurador le permitirá determinar si se espera que el valor de retorno.

Cuando el retorno es booleano, el valor real es totalmente implícita por el flujo de código, por lo que es menos crítica; sin embargo, bajo el mantenimiento del código que se encuentra más adelante que necesita ese resultado, por lo que puede decidir hacer un hábito en cualquier caso.

A pesar de que el valor de retorno es booleano, otra cuestión a considerar es si la función ha requerido efectos secundarios, y si esto puede ser afectada por la evaluación de cortocircuito. Por ejemplo, en la declaración:

if( isValid && fn() ) ...

la función nunca será llamada es isValid es falso.

Las circunstancias en que el código podría ser roto en mantenimiento por el programador incautos (y con frecuencia es que los programadores con menos experiencia que obtienen las tareas de mantenimiento) son muchas, y probablemente mejor evitar.

En este ejemplo específico, creo que depende de lo que haga lock(). Es la función de muy alto? Podría volver las cosas diferentes cada vez que la función se llama (que podría devolver un puntero la primera vez y la segunda vez NULL)? ¿Hay otro hilo conductor que podría intercalar entre las dos llamadas a lock()?

En este ejemplo, es necesario comprender el comportamiento de lock() y el resto de su código para tomar una decisión inteligente.

Yo prefiero el primero de ellos la mayor parte del tiempo, ya que hace que el código sea más clara y fácil de leer, por lo tanto, menos propenso a errores. Por ejemplo, se le olvidó un paréntesis en ese segundo ejemplo :) En este caso, en realidad, probablemente haría lo que hizo en el segundo ejemplo, sin embargo, si necesitaba usar ese submenú más de un par de veces me gustaría ir con el primero para hacer el código más fácil de leer. En cuanto a rendimiento, lo que cualquier compilador sano juicio sería capaz de optimizar eso (que es probablemente la razón por que vio ninguna diferencia en el rendimiento).

Además, como mmyers señalaron, que también depende de qué bloquear () lo hace. En general, si se trata de un método sencillo captador o algo por el estilo, se le multa.

Lo que usted prefiere. Para mí, depende de lo mucho que lo uso; por dos líneas, yo podría escribirlo en ambas ocasiones, mientras se crea una variable si lo uso más. Sin embargo, usted es el que más probablemente tendrá que mantener este código y seguir buscando en ella, por lo que su uso lo que funcione para usted. Por supuesto, si estás en una empresa con una pauta de codificación, seguirlo.

Creo que el estilo preferido es el estilo que piensa que hace que su código sea más legible y fácil de mantener. Si usted es un equipo de más de uno, la única otra consideración es que por lo general es una idea buena para todo el mundo a adoptar el mismo estilo, de nuevo por la legibilidad y facilidad de mantenimiento.

En este caso creo que debería utilizar el temporal. Incluso si conoce la aplicación de .lock () es de bajo costo, que puede cambiar. Si no es necesario bloqueo de llamadas () dos veces, no lo hacen. El valor aquí es que desacopla el código de la aplicación de bloqueo (). Y eso es una cosa buena en general.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top