Referencias como parámetros de función y referencias como valores de retorno de función

Parte del blog de referencia: http://t.csdn.cn/b5x99

Referencia como parámetro de función

Función: cuando una función pasa parámetros, puede usar la técnica de referencia para permitir que los parámetros formales modifiquen los parámetros reales

Ventajas: puede simplificar el puntero para modificar el parámetro real

Paso de valor: cuando la función llama al parámetro real, el valor se pasa al parámetro formal y el parámetro formal no puede modificar el parámetro real cuando se pasa el valor

Paso de dirección: cuando se llama a la función, el parámetro real pasa la dirección al parámetro formal

//1. 值传递
void mySwap01(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

//2. 地址传递
void mySwap02(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

//3. 引用传递
void mySwap03(int& a, int& b) {//注意这里,传参数时就是对引用的初始化
    int temp = a;
    a = b;
    b = temp;
}

int main() {

    int a = 10;
    int b = 20;

    mySwap01(a, b);
    cout << "a:" << a << " b:" << b << endl;

    mySwap02(&a, &b);
    cout << "a:" << a << " b:" << b << endl;

    mySwap03(a, b);
    cout << "a:" << a << " b:" << b << endl;

    system("pause");
    return 0;
}

 Resumen: el efecto de pasar parámetros por referencia es el mismo que pasar por dirección. La sintaxis para citar es más clara y sencilla.

Referencia como valor de retorno de la función

Puede existir una referencia como valor de retorno de una función. Cuando se utiliza una referencia como valor de retorno de una función, debe agregar & antes del nombre de la función al definir la función.

A continuación se presenta un análisis comparativo de las cuatro situaciones

Hay dos funciones fn1 y fn2, la temperatura es una variable global

//代码来源:RUNOOB
#include<iostream>
using namespace std;


float temp;//全局变量

float fn1(float r){
    temp=r*r*3.14;
    return temp;
} 

float &fn2(float r)//&说明返回的是temp的引用,换句话说就是返回temp本身
{ 
    temp=r*r*3.14;
    return temp;
}


int main(){
    float a=fn1(5.0); //case 1:返回值

    //float &b=fn1(5.0); //case 2:用函数的返回值作为引用的初始化值 [Error] invalid initialization of non-const reference of type 'float&' from an rvalue of type 'float'
                           //(有些编译器可以成功编译该语句,但会给出一个warning) 

    float c=fn2(5.0);//case 3:返回引用

    float &d=fn2(5.0);//case 4:用函数返回的引用作为新引用的初始化值

    cout<<a<<endl;//78.5
    //cout<<b<<endl;//78.5
    cout<<c<<endl;//78.5
    cout<<d<<endl;//78.5

    return 0;
}

caso 1: llamar a la función con valor de retorno

Al devolver el valor de la variable global temp, C++ creará una variable temporal en la memoria y copiará el valor de temp a la variable temporal . Después de volver a la función principal main, la sentencia de asignación a=fn1(5.0) copiará el valor de la variable temporal a la variable a

caso 2: llamar a la función inicializando la referencia con el valor de retorno de la función

En este caso, la función fn1() regresa por valor, al regresar primero copia el valor de temp a la variable temporal . Después de regresar a la función principal, use la variable temporal para inicializar la variable de referencia b , de modo que b se convierta en el alias de la variable temporal . Debido a que el alcance de las variables temporales es breve (en el estándar C++, el ciclo de vida de las variables u objetos temporales finaliza después de que finaliza una expresión de instrucción completa, es decir, después de que la instrucción float &b=fn1(5.0);), yb Es un alias para una variable temporal, por lo que b estará en peligro de no ser válido , y es muy probable que el valor en el futuro sea un valor indeterminado.

caso 3: llamar a la función devolviendo una referencia

En este caso, la función fn2() regresa por referencia, y devuelve temp en sí misma , no genera una copia, sino que devuelve directamente la variable temp a la función principal, es decir, el lvalue en la sentencia de asignación de la función principal Se copia directamente de la variable temp (es decir, c es solo una copia de la variable temp y no un alias ), evitando así la generación de variables temporales . Especialmente cuando la variable temp es un objeto de una clase definida por el usuario, esto también evita el proceso de llamar al constructor de copias en la clase para crear un objeto temporal en la memoria, mejorando la eficiencia del tiempo y el espacio en el programa.

caso 4: llame a la función utilizando la referencia devuelta por la función como el valor de inicialización de la nueva referencia

En este caso, el valor de retorno de la función fn2() no genera una copia, sino que devuelve directamente la variable temp a la función principal. En la función principal, se inicializa una declaración de referencia d con el valor de retorno, es decir, d se convierte en un alias de la variable temp en este momento. Dado que temp es una variable global, temp siempre seguirá siendo válida durante el período de validez de d, por lo que este enfoque es seguro.

Resumen: la mayor ventaja de usar referencias como valor de retorno de una función es que no se genera ninguna copia del valor de retorno en la memoria.

También debe tener cuidado de no devolver referencias de variables locales

//返回局部变量引用
int& test01() {
	int a = 10; //局部变量
	return a;
}

//返回静态变量引用
int& test02() {
	static int a = 20;//全局区
	return a;
}

int main() {

	//不能返回局部变量的引用
	int& ref = test01();
	cout << "ref = " << ref << endl;//ref=10
	cout << "ref = " << ref << endl;//乱码

	//如果函数做左值,那么必须返回引用
	int& ref2 = test02();
	cout << "ref2 = " << ref2 << endl;
	cout << "ref2 = " << ref2 << endl;

	test02() = 1000;

	cout << "ref2 = " << ref2 << endl;
	cout << "ref2 = " << ref2 << endl;

	system("pause");

	return 0;
}

Llame a la función test01, la primera salida es normal y la segunda salida está distorsionada

Además, si el valor de retorno de la función es una referencia, la llamada a la función se puede usar como un valor l.

Supongo que te gusta

Origin blog.csdn.net/hbzdsXCV/article/details/128355689
Recomendado
Clasificación