2010-06-01 5 views
5

Sólo por curiosidad acerca de por qué un parámetro tiene que ser una constante en la operación sobrecargaqué debe proporcionarle la palabra clave const en el operador de sobrecarga

CVector& CVector::operator= (const CVector& param) 
{ 
    x=param.x; 
    y=param.y; 
    return *this; 
} 

no podría haber hecho fácilmente algo como esto ??

CVector& CVector::operator= (CVector& param) //no const 
{ 
    x=param.x; 
    y=param.y; 
    return *this; 
} 

¿No es cuando algo se convierte en una constante, es inmutable para el resto de las aplicaciones de la vida? ¿Cómo difiere esto en la sobrecarga de operación?

Respuesta

2

Un parámetro es const const lo largo de la función de usarlo, que no cambia su constness fuera de ella.

En este caso, desea declarar un argumento const para que su operador de asignación acepte variables no const y variables const; el último caso, en particular, incluye el resultado de expresiones, que es una variable const temporal y que generalmente desea admitir en las asignaciones.

+0

O, ¿está diciendo que g = (a + b * c) el resultado en el lado derecho se considera una constante? Cuando dices que un const es solo un const dentro de la función. ¿Estás diciendo que una vez que la función se termina de ejecutar? Esos valores podrán cambiarse de nuevo? – numerical25

+0

¿Sabes qué? Tiene sentido ahora. Si lanzo un valor const a un varible. eso no hace que la varible sea una const, solo significa que ahora tiene el valor de la const que puede cambiarse – numerical25

+0

@numerical, ten en cuenta que tu idea solo funciona como lo que mencionaste si es pass-by-reference. – YeenFei

8

No es necesario const:

@ numerical25: Sólo por curiosidad acerca de por qué un parámetro tiene que ser una constante en la operación sobrecarga

No es necesario, pero es una buena decisión de diseño.

Ver el C++ sección estándar 12,8-9:

Una asignación de copia operador X :: operador-declarado user = es una función miembro no molde no estático de la clase X con exactamente un parámetro de tipo X, X &, const X &, volátil X & o const volátil X &


creo que es una buena idea sin embargo:

El uso de un parámetro const hace parece una decisión de diseño lógico para mí, porque aunque usted quiere asegurarse de que el otro valor no será cambiado.

Se dice que otras personas que utilizan su clase que no va a cambiar el valor other cuando se dice algo así como: myObject = other; y hace cumplir esto por lo que no puede cambiar accidentalmente other.

Además, si permites referencias no const al objeto como parámetro, entonces estás limitando la cantidad de objetos que pueden usar tu función. Si es const, se puede usar para parámetros const y non const. Si su parámetro no es const, solo puede ser utilizado por parámetros que no son const.


const sólo se aplica a la referencia actual, no el objeto:

@ numerical25: ¿No es cuando algo se convierte en una constante, es inmutable para el resto de la vida de las aplicaciones? ? ¿Cómo difiere esto en la sobrecarga de operación?

Una referencia de const es simplemente que una referencia que es const. No cambia la constidad del objeto real que está pasando.


Un ejemplo de sobrecarga de operadores no const:

Aquí es un ejemplo de la sobrecarga de operadores donde el parámetro no es const.
No recomiendo hacer esto sin embargo:

class B 
{ 
public: 
const B& operator=(B& other) 
{ 
    other.x = 3; 
    x = other.x; 
    return *this; 
} 

int x; 
}; 


void main(int argc, char** argv[]) 
{ 
B a; 
a.x = 33; 
B b; 
b.x = 44; 
a = b;//both a and b will be changed 
return 0; 
} 
+2

Y es 'const' para el alcance de la declaración, no la vida de la aplicación. – CuppM

+0

@CuppM: Sí, eso está implícito ya que toda la variable de referencia en sí también también está fuera del alcance. Sin embargo, no cambia la constidad del objeto original durante su alcance. Por ejemplo, si tiene 2 hilos. –

1

Si utilizó

CVector& CVector::operator= (CVector& param) // no const 

pues, tiene éste:

const CVector& my_vector = GetMyVector(); 
some_other_vector = my_vector; // call assignment operator - error! 

Usted obtendrá un error porque my_vector es una const CVector& y que no se puede convertir a un (no constante CVector& referencia). Es solo la referencia local dentro de la función operator= que es const, no el objeto completo en sí mismo.

0

Por la misma razón, utilizaría const en cualquier lugar: para garantizar que los cambios futuros en el método no modifiquen inadvertidamente el parámetro pasado, para ayudar a documentar la interfaz para notificar a las personas que llaman que es seguro pasar el parámetro sin riesgo de está cambiando, y para permitir que las personas que llaman pasen las referencias que están declaradas como const en el código de llamada.

1

Puede usar la variedad sin contraste, pero esto tiene dos repercusiones, una que es funcional, y otra que es lo que usted, como autor de la función, le está diciendo al usuario.

1) la gente que llama a la función que toma una referencia no const no sería capaz de llamar usando una variable const

2) cuando se tiene un argumento de una función que es una referencia no const, eres señalización, "reservo el derecho de cambiar esto". Normalmente, cuando un usuario de su función escribe a = b ;, no espera que b cambie.

Tenga en cuenta que hay una tercera opción se puede utilizar para esto, el paso por valor:

CVector& CVector::operator= (CVector param) //no reference 

Esto no tiene ninguno de los problemas que menciono arriba. Sin embargo, es muy ineficiente. Debido a estos tres factores, se prefiere pasar por referencia a const, especialmente en casos como un vector donde la copia puede ser costosa.

0

Otro motivo es permitir conversiones. Por ejemplo:

string s = "foo"; 
s = "bar"; 

Aquí, una aplicación puede optar por sólo proporcionan el operador de asignación que toma una referencia constante a una cadena como parámetro, y dependerá del compilador utilizando un constructor para crear una cadena temporal del carbón de leña * "bar". Esto no funcionaría si el parámetro op = no fuera const, ya que no puede vincular una referencia temporal a una referencia no constante.

0

El calificador const hace que el parámetro pasado (en su ejemplo sea 'const CVector & param') como de solo lectura. El calificador const garantiza que el parámetro (param) no se altera dentro del método operator =().

Sin el calificador const, la siguiente es posible:

CVector& CVector::operator= (CVector& param) 
{ 
    x=param.x; 
    y=param.y; 

    param.x = 10; // some random value 
    param.y = 100; 

    return *this; 
} 

El método anterior altera los secundarios operando de la mano derecha 'PARAM' después de asignar el valor al operando de la parte izquierda. El calificador const le ayuda a no violar la semántica de la operación de asignación.

Cuestiones relacionadas