¿Es una buena práctica para pasar objeto struct como parámetro a una función en C ++?

StackOverflow https://stackoverflow.com/questions/2724708

  •  02-10-2019
  •  | 
  •  

Pregunta

I trató un ejemplo vivo a continuación:

typedef struct point
{
    int x;
    int y;
} point;

void cp(point p)
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
}

Las eso es resultado impreso a cabo es:

1
2

que es lo que esperaba. Mi pregunta es: ¿El parámetro p obtener una copia completa de p1 objeto? Si es así, me pregunto si esto es una buena práctica? (Asumí cuando la estructura se pone grande en tamaño, esto creará una gran cantidad de gastos generales copia).

¿Fue útil?

Solución

No hay nada malo con el paso de estructuras como parámetros. Todo se pasa por valor en C ++ por lo que una copia completa de hecho se hizo.

La estructura que diste en tu ejemplo es pequeño, así que probablemente no es un problema si se le pasa por valor. Pero si se trabaja con estructuras de datos más grandes, es posible que desee pasar por referencia.

Sin embargo, Aviso, pasando por los medios de referencia, si se modifica la estructura dentro de su función, se modificará su estructura inicial. Asegúrese de utilizar la palabra clave const en todos los casos en que no modifique la estructura. Esto le dará una información inmediata sobre si sus funciones hacen modificar la información o no.

Su ejemplo podría ser modificado para trabajar con referencias de esta manera:

typedef struct point
{
    int x;
    int y;
} point;

void cp(const point& p) // You can know that cp doesn't modify your struct
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

void mod_point(point& p) // You can know that mod_points modifies your struct
{
    p.x += 1;
    p.y += 1;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
    mod_point(p1);
    cp(p1); // will output 2 and 3
}

Otros consejos

Sí, no hay nada malo con esto y sí, p es una copia completa de p1. Yo no lo llamaría un struct con dos ints grande, pero si el struct se pone grande y si no es necesario modificarlo en el cuerpo de la función que podría considerar la aprobación por referencia constante:

void cp(const point& p)
{
    // ...
}

Antes de dar una respuesta a su pregunta (le resulta al final de este post), aquí está un resumen breve de las posibilidades que tiene para pasar argumentos a una función:


1. objetos construidos-Copy (pase-por-valor):

void cp(point p);

Este es el paso por valor. Un objeto point temporal se crea y construye copia-de cualquier objeto que se pasa en point cp. Una vez que las hojas de ejecución de la función cp, el objeto temporal se destruye.

Tenga en cuenta que debido a que la función opera en una copia de todo lo que se pasa a la función, puede modificar ese objeto point local, tanto como desea, el objeto original de la persona que llama no se verá afectado. No hay manera de cambiar este comportamiento con parámetros pase-por-valor.


2. Las referencias a objetos (pase por referencia):

void cp(point& p);

Este es el paso por referencia. El objeto real pasa a la función está disponible (y potencialmente sujeto a modificación) dentro de la función. Si no desea que la función sea capaz de cambiar el pasado-en objeto, declarar el parámetro como const point&:

void cp(const point& p);

3. Los punteros a objetos (pase por referencia):

void cp(point* p);

Este es también el paso por referencia, con algunas diferencias sutiles. Una diferencia notable es que se puede pasar un puntero nulo a la función. Esto no es posible con referencias, ya que las referencias debe ser inicializado y no pueden ser recolocados después. - Como con referencias, si quieres cp disallow de cambiar el pasado-en point, la declara como const:

void cp(const point* p);

respuesta a su pregunta:

parámetros de Pass-a-valor no son intrínsecamente mala de ninguna manera. Por supuesto, hay tipos para que construcción copia es caro (objetos, por ejemplo, muy grandes o complejos), o donde tiene ciertos efectos secundarios (por ejemplo, con std::auto_ptr). En estos casos, se debe tener cuidado. De lo contrario, es sólo otra de las características de C ++ que tiene sus usos perfectamente razonables.

void cp(point p){
}

lo consigue por valor

void cp(point *p){
}

lo consigue por referencia

Al igual que cualquier otra variable de datos.

En Java el escenario es diferente. objetos que pasan siempre van por referencia.

En caso de que la estructura que punto se pasa "por valor", es decir, que toda la estructura se copia. Para los tipos de datos grandes, este hecho puede ser lento.

Se puede considerar pasar el objeto por referencia

void cp(point& p) // p may be altered!

o ser referencia const

void cp(const point& p) // p may not be altered!

ver las posibilidades para evitar pasar objetos por valor. El objetivo no es sólo 'copiado', pero es copiar construido. Por lo tanto, se trata de llamar al constructor de copia y la cadena de constructores de copia si su objeto está compuesto o derivado de más objetos. El paso por referencia si es posible.

vacío cp (point & p const) const {

    cout << p.x << endl;
    cout << p.y << endl;

}

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