variable son reglas que para nombrar las inicializar dev declarar declaracion crear como arreglos c++ return-value scope

reglas - que son las variables de c++



Alcance y valores devueltos en C++ (6)

Cuando la función termina, ocurren los siguientes pasos:

  • El valor de retorno de la función se copia en el marcador de posición que se colocó en la pila para este propósito.

  • Todo después de que el puntero del marco de pila se destacó. Esto destruye todas las variables y argumentos locales.

  • El valor de retorno se saca de la pila y se asigna como el valor de la función. Si el valor de la función no está asignado a nada, no se realiza ninguna asignación, y el valor se pierde.

  • La dirección de la siguiente instrucción para ejecutar se saca de la pila y la CPU reanuda la ejecución en esa instrucción.

La pila y el montón

Estoy empezando de nuevo con c ++ y estaba pensando en el alcance de las variables. Si tengo una variable dentro de una función y luego devuelvo esa variable, ¿la variable no estará "muerta" cuando se devuelva porque el alcance en el que estaba terminó?

He intentado esto con una función que devuelve una cadena y funcionó. ¿Alguien puede explicar esto? O al menos dirígeme a algún lugar que pueda explicarme esto por favor.

Gracias


Cuando devuelve un valor, se realiza una copia. El alcance de la variable local finaliza, pero se realiza una copia y se devuelve a la función de llamada. Ejemplo:

int funcB() { int j = 12; return j; } void A() { int i; i = funcB(); }

El valor de j (12) se copia y se devuelve a i para que reciba el valor de 12.


La variable local se copia al valor de retorno. Los constructores de copia se llaman para clases no triviales.

Si devuelve un puntero o una referencia a una variable local, tendrá problemas, tal como lo sugirió su intuición.


Realmente depende de qué tipo de variable estés devolviendo. Si devuelve una primitiva, se devuelve mediante copia, no por referencia, de modo que el valor se copia en la parte superior de la pila (o, más a menudo, se coloca en un registro) donde la función llamante puede obtenerlo. Si asigna un objeto o memoria en el montón y devuelve un puntero, entonces no muere porque está en el montón, no en la pila. Sin embargo, si asigna algo en la pila y lo devuelve, sería algo malo. Por ejemplo, cualquiera de estos sería muy malo:

int *myBadAddingFunction(int a, int b) { int result; result = a + b; return &result; // this is very bad and the result is undefined } char *myOtherBadFunction() { char myString[256]; strcpy(myString, "This is my string!"); return myString; // also allocated on the stack, also bad }


Solo por un poco más de una explicación orientada al modelo de memoria: cuando se llama a una función, se crea un espacio temporal para que la función coloque sus variables locales, llamadas un marco . Cuando la función (llamada) devuelve su valor, pone el valor de retorno en el marco de la función que lo llamó (llamador), y luego se destruye el marco invocador.

La parte "marco es destruido" es la razón por la que no puede devolver punteros o referencias a variables locales desde funciones. Un puntero es efectivamente una ubicación de memoria, por lo que devolver la ubicación de memoria de una variable local (por definición: una variable dentro del marco) se vuelve incorrecta una vez que se destruye el marco. Como el marco invocable se destruye tan pronto como devuelve su valor, cualquier puntero o referencia a una variable local es inmediatamente incorrecto.


Esto depende del tipo de artículo devuelto. Si regresa por valor, se realiza una nueva copia de la variable para devolverla a la persona que llama. En este caso, no tiene que preocuparse por la duración del objeto, pero puede que tenga que preocuparse por los costos de copiar objetos (pero no optimice prematuramente; la corrección es mucho más importante):

std::string someFunc( std::string& const s) { return s + "copy"; }

Si la función devuelve una referencia, debe tener cuidado con lo que está devolviendo porque su vida útil debe extenderse más allá de la duración de la función y la persona que llama no necesariamente podrá delete si está utilizando una función new para crear la referencia. objeto:

std::string& someFunc2( std::string const& s) { return s + "reference to a copy"; // this is bad - the temp object created will // be destroyed after the expression the // function call is in finishes. // Some, but not all, compilers will warn // about this. }

Por supuesto, devolver los punteros tendrá consideraciones similares de por vida.