¿Cuándo pasamos argumentos por referencia o puntero?

En C++, las variables se pasan por referencia por las siguientes razones:
1) Para modificar las variables locales de la función que llama: una referencia (o puntero) permite que la función llamada modifique una variable local de la función que llama. Por ejemplo, considere el siguiente programa de ejemplo donde fun() puede modificar la variable local x de main() .
 

CPP

#include <bits/stdc++.h>
using namespace std;
 
void fun(int& x) { x = 20; }
 
int main()
{
    int x = 10;
    fun(x);
    cout << "New value of x is " << x;
    return 0;
}

Salida: 
el nuevo valor de x es 20
2) Para pasar argumentos de gran tamaño: si un argumento es grande, pasar por referencia (o puntero) es más eficiente porque solo se pasa una dirección, no todo el objeto. Por ejemplo, consideremos la siguiente clase de empleado y una función printEmpDetails() que imprime los detalles del empleado.
 

C

class Employee {
private:
    string name;
    string desig;
 
    // More attributes and operations
};
 
void printEmpDetails(Employee emp)
{
    cout << emp.getName();
    cout << emp.getDesig();
 
    // Print more attributes
}

El problema con el código anterior es: cada vez que se llama a printEmpDetails() , se construye un nuevo objeto Employee que implica la creación de una copia de todos los miembros de datos. Entonces, una mejor implementación sería pasar a Employee como referencia.
 

C

void printEmpDetails(const Employee& emp)
{
    cout << emp.getName();
    cout << emp.getDesig();
 
    // Print more attributes
}

Este punto es válido solo para variables de estructura y clase, ya que no obtenemos ninguna ventaja de eficiencia para tipos básicos como int, char, etc. 
3) Para evitar el corte de objetos: si pasamos un objeto de subclase a una función que espera un objeto de superclase, el objeto pasado se corta si se pasa por valor. Por ejemplo, considere el siguiente programa, imprime «This is Pet Class». 
 

C

#include <iostream>
 
using namespace std;
 
class Pet {
public:
    virtual string getDescription() const
    {
        return "This is Pet class";
    }
};
 
class Dog : public Pet {
public:
    virtual string getDescription() const
    {
        return "This is Dog class";
    }
};
 
void describe(Pet p)
{ // Slices the derived class object
    cout << p.getDescription() << '\n';
}
 
int main()
{
    Dog d;
    describe(d);
    return 0;
}

Salida: 
Esta es la clase de mascotas
Si usamos pasar por referencia en el programa anterior, se imprime correctamente «Esta es la clase de perros». Ver el siguiente programa modificado.
 

C++

#include <iostream>
 
using namespace std;
 
class Pet {
public:
    virtual string getDescription() const
    {
        return "This is Pet class";
    }
};
 
class Dog : public Pet {
public:
    virtual string getDescription() const
    {
        return "This is Dog class";
    }
};
 
void describe(const Pet& p)
{ // Doesn't slice the derived class object.
    cout << p.getDescription() << '\n';
}
 
int main()
{
    Dog d;
    describe(d);
    return 0;
}

Salida: 
esta es la clase de perro
. Este punto tampoco es válido para tipos de datos básicos como int, char, etc.
4) Para lograr el polimorfismo de tiempo de ejecución en una función. Podemos hacer que una función sea polimórfica pasándole objetos como referencia (o puntero). . Por ejemplo, en el siguiente programa, print() recibe una referencia al objeto de la clase base. La función print() llama a la función de la clase base show() si se pasa el objeto de la clase base, y a la función de la clase derivada show() si se pasa el objeto de la clase derivada.  

 

C++

#include <iostream>
using namespace std;
 
class base {
public:
    virtual void show()
    { // Note the virtual keyword here
        cout << "In base\n";
    }
};
 
class derived : public base {
public:
    void show() { cout << "In derived\n"; }
};
 
// Since we pass b as reference, we achieve run time
// polymorphism here.
void print(base& b) { b.show(); }
 
int main(void)
{
    base b;
    derived d;
    print(b);
    print(d);
    return 0;
}

Salida: 
En base 
En derivado 
Gracias a Venki por agregar este punto. 
Como nota al margen, es una práctica recomendada hacer que los argumentos de referencia sean constantes si se pasan por referencia solo debido a la razón no. 2 o 3 mencionados anteriormente. Esto se recomienda para evitar modificaciones inesperadas en los objetos.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *