2011-08-01 34 views
5

Al leer documentación sobre funciones de bibliotecas externas de diferentes tipos, siempre he visto que la documentación indica que una variable debe ser [IN/OUT]. ¿Podría alguien darme una comprensión detallada de cómo [IN/OUT] se relaciona con los parámetros de una función que se pasa por referencia o por valor?Parámetros IN/OUT y cómo trabajar con ellos en C++

Aquí es un ejemplo de una función que he encontrado que me dice que necesita un [IN/OUT] parámetro:

Prototipo: ULONG GetActivationState (ULONG * pActivationState);

Parámetros

  • Tipo: ULONG *
  • variable: pActivationState
  • modo: IN/OUT

Respuesta

2

Si un parámetro está fuera, se tiene que ser aprobado por re Ference. Un parámetro puramente IN se pasa generalmente por valor o referencia constante, si el costo de copiado es demasiado alto (nada impide que el diseño lo pase por referencia, pero no es muy bueno diseño en mi humilde opinión). Un parámetro IN/OUT se debe pasar por referencia.

+1

'Un parámetro IN/OUT se debe pasar por referencia'; excepto en el ejemplo publicado, un parámetro ENTRADA/SALIDA se pasa por un puntero. – Praetorian

+3

@Praetorian: "pasar por referencia" no significa forzosamente que la firma utiliza una referencia de C++ para el parámetro. Significa que la función tiene acceso de escritura a la variable en lugar de una copia del valor de la variable. –

+1

@ André Caron Veo lo que dices, pero no estoy de acuerdo. Si esto fuera C, usaría los términos "pasar por puntero" y "pasar por referencia" de manera intercambiable, pero con C++ hay una diferencia, por lo que creo que la distinción es importante.Tal vez solo soy quisquilloso :-) – Praetorian

5

En general, las cosas marcadas como IN/OUT se pasarán a través de un puntero o referencia no const, permitiendo que la función modifique la variable directamente, y también la lea. Asegúrese de verificar la documentación para ver si espera que se establezca el valor antes de pasarlo.

Los parámetros marcados como IN se pasarán por valor, o por puntero constante o referencia constante, impidiendo que la función modifique la variable.

C++ no exige parámetros de solo SALIDA, pero en general se aprobarán utilizando punteros no const o referencias, similares a IN/OUT.

+0

Incluso cuando la documentación no requiere que se establezca un valor, igual recomiendo asignar algún valor seguro a la función. Por ejemplo, si la función devuelve un puntero por referencia (por ejemplo, 'void ** p'), asigne el puntero 0 antes de invocar la función. –

7

Este parámetro está dentro/fuera porque proporciona un valor que se utiliza dentro de la función, y, la función lo modifica para informarle acerca de algo que sucedió dentro de la función. El uso de esta función sería algo como esto:

ULONG activationState = 1; // example value 
ULONG result = GetActivationState(&activationState); 

nota que usted tiene que suministrar la dirección de la variable de modo que la función se puede obtener el valor y establecer el valor fuera de la función. Por ejemplo, la función GetActivationState puede realizar algo como esto:

ULONG GetActivationState(ULONG* pActivationState) 
{ 
    if (*pActivationState == 1) 
    { 
    // do something 
    // and inform by the modification of the variable, say, resetting it to 0 
     *pActivationState = 0; 
    } 
    // ... 
    return *pActivationState; // just an example, returns the same value 
} 

Nota cómo:

  1. La función acepta el parámetro como un puntero no constante a un UINT. Esto significa que puede modificarlo.
  2. La función puede acceder al valor que le dio al parámetro desreferenciando
  3. La función puede modificar el parámetro nuevamente al quitarle la referencia.
  4. La función de llamada ve la variable activationState sosteniendo el nuevo valor (0 en este caso).

Este es un ejemplo de "paso por referencia", que se realiza mediante el uso de punteros en C (y también con referencias en C++.)

0

Puede utilizar por valor (simplemente tipos) o por la constante referencia const & para parámetros de solo entrada. Use la referencia no constante & o el puntero * como parámetro in/out para cambiar el valor de la variable. También puede usar una referencia de puntero * & para permitirle cambiar la dirección a la que apunta el puntero real (entrada/salida). Como Dave Smith señaló que no hay un solo parámetro en C++.

4

Esta parte se aplica a todos los tipos de parámetros: la mayoría de las interfaces de biblioteca intentan ser compatibles con C, por lo que es más común pasar parámetros por puntero que por referencia.

IN: Cuando un parámetro se enumera como IN, la interfaz ofrece una garantía de que no modificará ese parámetro. En mi opinión, esto se transmite mejor marcando el parámetro como const, luego el lenguaje mismo evitará modificaciones al valor. Si este parámetro se pasa por valor, no tiene importancia si está marcado IN en la documentación (o const en el prototipo) ya que el parámetro es local para la función de todos modos. Pero para evitar la copia, se puede pasar por referencia o por puntero, en cuyo caso la palabra clave const se vuelve muy importante.

OUT: Un parámetro marcado OUT generalmente significa que el valor del parámetro cuando se pasa a la función no tiene ninguna importancia. De hecho, si se pasa por un puntero, incluso puede requerirse que sea NULL, y la función asignará memoria y le devolverá un valor.

ENTRADA/SALIDA: Un parámetro IN/OUT generalmente indica algo donde los valores de entrada y salida son significativos. Por ejemplo, si tiene una función de biblioteca que llena un búfer, puede requerir que pase un puntero al búfer, junto con otro puntero que indica la longitud del búfer. Cuando la función retorna, el segundo puntero puede contener la cantidad real de bytes que se han escrito en el búfer.

2

Tengo una mente mixta con respecto al uso de entrada, salida y entrada/salida.

Al revés: Cuando se realiza correctamente, comunica intenciones al lector de la documentación.

Desventaja: con demasiada frecuencia no se realiza correctamente. Esas designaciones obviamente no son parte del lenguaje; están en comentarios o en algún documento que se mantiene por separado del código. He visto demasiados casos en los que un parámetro se marcó como "fuera", pero lo primero que se hace en el código con ese parámetro es usarlo como un valor del lado derecho.

Cuestiones relacionadas