constint - Pregunta de novato: c++ const a conversión no const.
const javascript (4)
Estoy realmente molesto por la palabra clave const
estos días, ya que no estoy muy familiarizado con ella. Tenía un vector que almacena todos los punteros const, como vector<const BoxT<T> *> *Q_exclude
, y en el constructor de otra clase, necesito que un elemento de esta cola se pase como parámetro y lo asigne a un no -const miembro. Mi pregunta es:
¿Cómo asigno una variable const a una variable no const? Sé que esto no tiene sentido porque, después de todo, una const es una const, y no debe cambiarse por ningún medio. ¡Pero esa molesta variable miembro REALMENTE tiene que cambiarse durante el proceso! También podría cambiar el tipo de datos en el vector para que no sea const, pero eso sería demasiado trabajo. ¿O alguien sabe cómo evitar tal situación?
Cambiar un tipo constante conducirá a un comportamiento indefinido .
Sin embargo, si tiene un objeto original no constante al que apunta un puntero a la constante o referenciado por una referencia a la constante, entonces puede usar const_cast para deshacerse de esa constante.
Desechar la constancia es considerado un mal y no debe ser evitado. Debería considerar cambiar el tipo de los punteros que usa en vector a no constantes si desea modificar los datos a través de él.
El código real para descartar la const-ness de su puntero sería:
BoxT<T> * nonConstObj = const_cast<BoxT<T> *>(constObj);
Pero tenga en cuenta que esto realmente es trampa. Una mejor solución sería averiguar por qué desea modificar un objeto const y rediseñar su código para que no tenga que ... o eliminar la declaración const de su vector, si resulta que no lo hace realmente quiero que esos elementos sean de solo lectura después de todo.
Puede asignar un objeto const
a un objeto no const
simplemente bien. Debido a que está copiando y creando un nuevo objeto, no se viola la constancia.
int main() {
const int a = 3;
int b = a;
}
Es diferente si desea obtener un puntero o una referencia al objeto original, const
:
int main() {
const int a = 3;
int& b = a; // or int* b = &a;
}
// error: invalid initialization of reference of type ''int&'' from
// expression of type ''const int''
Puede utilizar const_cast
para piratear el tipo de seguridad si realmente debe hacerlo, pero recuerde que está haciendo exactamente eso: deshacerse del tipo de seguridad. Todavía no está definido modificar a
través de b
en el siguiente ejemplo :
int main() {
const int a = 3;
int& b = const_cast<int&>(a);
b = 3;
}
A pesar de que se compila sin errores, puede ocurrir cualquier cosa, incluso abrir un agujero negro o transferir todos mis ahorros ganados a mi cuenta bancaria.
Si ha llegado a lo que cree que es un requisito para hacer esto, revisaría su diseño con urgencia porque algo está muy mal.
void SomeClass::changeASettingAndCallAFunction() const {
someSetting = 0; //Can''t do this
someFunctionThatUsesTheSetting();
}
Otra solución es llamar a dicha función entre modificaciones de las variables que utiliza la función const. Esta idea fue la que resolvió mi problema ya que no estaba dispuesto a cambiar la firma de la función y tuve que usar el método "changeASettingAndCallAFunction" como mediador:
Cuando llama a la función, primero puede realizar ediciones en la configuración antes de la llamada, o (si no está dispuesto a meterse con el lugar de invocación) quizás llame a la función en la que necesita el cambio de la variable a propagar (como en mi caso).
void SomeClass::someFunctionThatUsesTheSetting() const {
//We really don''t want to touch this functions implementation
ClassUsesSetting* classUsesSetting = ClassUsesSetting::PropagateAcrossClass(someSetting);
/*
Do important stuff
*/
}
void SomeClass::changeASettingAndCallAFunction() const {
someFunctionThatUsesTheSetting();
/*
Have to do this
*/
}
void SomeClass::nonConstInvoker(){
someSetting = 0;
changeASettingAndCallAFunction();
}
Ahora, cuando se invoca alguna referencia a "someFunctionThatUsesTheSetting", se invocará con el cambio a someSetting.