2010-04-28 21 views
8

Sé que si escribe nulo nombre_función (int & a), la función no hará copia local de su variable pasada como argumento. También me he encontrado en la literatura que debes escribir void function_name (const int & a) para decir compilador, que no quiero que la variable pasada como argumento sea copiada.Diferencia de argumento de función como (const int &) y (int & a) en C++

Así que mi pregunta: ¿cuál es la diferencia con estos dos casos (excepto que "const" asegura que la variable pasada no cambiará por la función !!!) ???

+0

¿No es la diferencia entre 'const int y a' y' a '' int o incluso const int a' el punto real? Me pregunto por qué el compilador debería marcar la diferencia entre 'const int & a' y' const int a'? ¿O usa y garantiza que el compilador no hará una copia y 'const int a' lo forzará a hacer una copia? ¿Cómo se puede decir 'dejar que el compilador elija'? – kriss

+0

Vea también aquí: http://stackoverflow.com/questions/2139224/2139254#2139254 – sbi

+1

@kriss: El compilador no puede elegir. Considere que declara una función 'void f ( int x);'. En el momento de la declaración, el compilador no tiene información sobre si va a cambiar o no el objeto. Solo al ver el código puede afirmar que el código no cambia o cambia el parámetro. Y aun así, si el código cambia un parámetro, ¿cómo puede el compilador saber si desea que ese cambio sea visible fuera de la función? Incluso si pudiera decidir con la definición, ¿cómo consideraría el compilador la firma en unidades de traducción donde solo se incluye el encabezado? –

Respuesta

10

Debe usar const en la firma cada vez que no necesite escribir. Agregar const a la firma tiene dos efectos: le dice al compilador que desea que verifique y le garantiza que no cambia ese argumento dentro de su función. El segundo efecto es que permite que el código externo use su función para pasar objetos que son a su vez constantes (y temporales), permitiendo más usos de la misma función.

Al mismo tiempo, la palabra clave const es una parte importante de la documentación de su función/método: la firma de la función dice explícitamente qué pretende hacer con el argumento y si es seguro pasar un objeto que es parte de las invariantes de otro objeto en tu función: estás siendo explícito porque no te meterás con su objeto.

El uso de const obliga a un conjunto más estricto de requisitos en su código (la función): no puede modificar el objeto, pero al mismo tiempo es menos restrictivo en sus llamadores, haciendo que su código sea más reutilizable.

void printr(int & i) { std::cout << i << std::endl; } 
void printcr(const int & i) { std::cout << i << std::endl; } 
int main() { 
    int x = 10; 
    const int y = 15; 
    printr(x); 
    //printr(y); // passing y as non-const reference discards qualifiers 
    //printr(5); // cannot bind a non-const reference to a temporary 
    printcr(x); printcr(y); printcr(5); // all valid 
} 
7

So my question: what is the difference with this two cases (except that "const" enshures that the variable passes will not be changed by function!!!)???

Eso es la diferencia.

+0

Me refiero al aspecto de la copia. – Narek

+0

@Narek: el 'const' no afecta si se realiza o no una copia. Pasar por referencia ('const' o no) evitará una copia. Pasar por el valor (no usar una referencia) causará una copia, ya sea que el parámetro sea 'const' o no.El uso de un parámetro de referencia 'const' para un' int' generalmente se considera innecesario, ya que pasar por el valor no tiene un costo adicional en ese caso. –

+0

@Michael: y ¿qué pasa con 'const int' vs' int'? – kriss

1

Usted establece la diferencia correcta. También puede formular como:

Si desea especificar que la función puede cambio el argumento (es decir, para init_to_big_number(int& i) especificando el argumento de() de referencia variable En caso de duda, especificarlo const

..

Tenga en cuenta que el beneficio de no copiar el argumento está en el rendimiento, es decir, para objetos 'caros'. Para tipos incorporados como int, no tiene sentido escribir void f(const int& i). Pasar la referencia a la variable es tan caro como pasar el valor

0

Se utilizan para diferentes fines es. Al pasar una variable usando const int& se asegura que obtendrá la semántica de paso a paso con un rendimiento mucho mejor. Se le garantiza que la función llamada (a menos que haga algunas cosas locas usando const_cast) no modificará su argumento pasado sin crear una copia. int& se usa cuando generalmente hay múltiples valores devueltos por una función. En ese caso, estos pueden ser utilizados para mantener los resultados de la función.

+2

Pero no se pasa por la semántica de copia con 'const int &'. Los cambios externos al objeto pasado serán visibles dentro de la función llamada. Esto definitivamente no es un pase por copia semántica, es una característica de pasar por referencia. –

1

Hay una gran diferencia en términos de parámetros que pudieran operar en, Digamos que tiene un constructor de copia para su clase de int,

customeclass(const int & count){ 
    //this constructor is able to create a class from 5, 
    //I mean from RValue as well as from LValue 
} 
customeclass(int & count){ 
    //this constructor is not able to create a class from 5, 
    //I mean only from LValue 
} 

La versión const puede operar esencialmente de valores temporales y no constante la versión no podría funcionar de forma temporal, usted fácilmente enfrentaría un problema cuando se pierda const donde se necesita y use STL, pero recibirá un mensaje de error diciendo que no pudo encontrar la versión que toma temporalmente. Recomiendo usar const siempre que puedas.

0

diría que

void cfunction_name(const X& a); 

me permite pasar una referencia al objeto de la siguiente manera temporal

X make_X(); 

function_name(make_X()); 

Mientras

void function_name(X& a); 

falla para lograr esto. con el siguiente error error: inicialización no válida de referencia no const del tipo 'X &' de un temporal de tipo 'X'

0

omitiendo la discusión sobre el rendimiento, ¡dejemos hablar el código!

void foo(){ 
    const int i1 = 0; 
    int i2 = 0; 
    i1 = 123; //i gets red -> expression must be a modifiyble value 
    i2 = 123; 
} 
//the following two functions are OK 
void foo(int i) { 
    i = 123; 
} 
void foo(int & i) { 
    i = 123; 
} 
//in the following two functions i gets red 
//already your IDE (VS) knows that i should not be changed 
//and it forces you not to assign a value to i 
//more over you can change the constness of one variable, in different functions 
//in the function where i is defined it could be a variable 
//in another function it could be constant 
void foo(const int i) { 
    i = 123; 
} 
void foo(const int & i) { 
    i = 123; 
} 

usando "const" donde se necesita tiene las siguientes ventajas: * puede cambiar el constness de una variable i, en diferentes funciones en la función donde i se define Podría ser una variable en otra función podría ser un valor constante. * ya su IDE sabe que no debería ser cambiado. y que le obliga a no asignar un valor a i

respecto Vaya

Cuestiones relacionadas