[C con Clase] ¿const_cast aconsejable o no?

Carlos Falgueras García fark.zano en gmail.com
Mie Mar 10 14:27:27 CET 2010


Supongo que al final terminaré quitándole el const.
En cuanto a lo de declarar la constante, no se si te he entendido bien, te
refieres a algo como esto:

int algoritmoComplejo(int i){
   return i*2;
}


class MiClase{

public:

  const int atributo_constante;


  MiClase(int argumentos) : atributo_constante(0){

    atributo_constante = algoritmoComplejo(argumentos);

  }


};
Ejecutar en codepad <http://codepad.org/rQjjVpLY> (
http://codepad.org/rQjjVpLY)

Esto da error, "assignment of read-only data-member". Si embargo algo como
esto si funciona:

int algoritmoComplejo(int i){
   return i*2;}
class MiClase{public:
  const int atributo_constante;

  MiClase(int argumentos) : atributo_constante(algoritmoComplejo(argumentos)){
     cout << atributo_constante << endl;
  }
};

Ejecutar en codepad <http://codepad.org/DarEDbob> (http://codepad.org/DarEDbob)

Pero en mi caso esto no es viable porque yo tengo dos atributos
constantes que mi algoritmo calcula de una sola vez, y tener que
inicializarlos así obliga a tener que ejecutar el algoritmo dos veces
(una para cada atributo) :S

Que no os mosquee tanto "secretismo" entorno a "mi algoritmo" XD, es
que es bastante grande para pegarlo aquí, tendría que explicar muchas
más cosas y liaría más que ayudar, por eso estoy usando estos
ejemplitos simples :P . A escala reducida yo tendría que hacer algo
así (o quitar el const de los atributos XD)

int algoritmoComplejo1(int atrb){
   int val_at1=0,val_at2=0;  //valor de los atributos

   for(int i = 0 ; i < atrb ; i++){
     val_at1++;
     val_at2 += val_at1;
   }
   return val_at1;}
int algoritmoComplejo2(int atrb){
   int val_at1=0,val_at2=0;  //valor de los atributos

   for(int i = 0 ; i < atrb ; i++){
     val_at1++;
     val_at2 += val_at1;
   }
   return val_at2;}
class MiClase{public:
  const int atributo_constante1;
  const int atributo_constante2;

  MiClase(int argumentos) :
     atributo_constante1(algoritmoComplejo1(argumentos)),
     atributo_constante2(algoritmoComplejo2(argumentos))
  {
     cout << atributo_constante1 << "," << atributo_constante2 << endl;
  }
};

Ejecutar en codepad <http://codepad.org/y6KT3iFz> (http://codepad.org/y6KT3iFz)


Bueno, lo dicho, terminaré quitando los const, pero de todas si
encuentro alguna solución alternativa la enviaré por si a alguien le
sirve o le pica la curiosidad.

Muchas gracias Jose por tu ayuda.


El 10 de marzo de 2010 12:26, Jose Cabrera <josmaca en gmail.com> escribió:

> Pues la verdad es que no, cada compilador traduce tu código de una manera,
> pero una vez compilado siempre va actuar de la misma forma, solo tienes que
> asegurarte del compilador que uses tu.
>
> De todas formas si, a parte del constructor, no creas ninguna otra función
> publica desde la cual puedas modificar el valor, para todo aquello que este
> fuera de la clase ese valor va a ser una constante, de todas formas tengo
> una duda que no recuerdo si se puede hacer o no y si alguien lo sabe te
> podría solucionar el problema, me explico:
>
> Una constante le das el valor la primera vez que la declaras
> const int aux = 1;
> , mi pregunta cuando creas un constructor el valor que le das se puede
> almacenar de igual forma en la constante?, si esto es posible podrias
> realizar el calculo del algortimo aparte y ingresar el valor en el
> constructor.
>
> El 10 de marzo de 2010 10:55, Carlos Falgueras García <fark.zano en gmail.com
> > escribió:
>
> Gracias por responder Jose!
>>
>> En principio este atributo sólo se modifica en el constructor de la
>> clase, y por esto lo quiero declarar constante.
>> Mi única duda es: ¿Puedo garantizar que el atributo se modifique use
>> el compilador que use?
>>
>> En el curso se dice que en algunos compiladores (DevC++ en concreto),
>> aún utilizando const_cast, la variable no se modifica. ¿Ocurre lo
>> mismo con los atributos de una clase?
>>
>> El 10/03/10, Jose Cabrera <josmaca en gmail.com> escribió:
>> > El atributo esta dentro de una clase con lo cual únicamente se podrá
>> > modificar desde dentro de esa clase, o con una clase amiga, si aun así
>> > necesitas que sea constante, desde mi punto de vista ya esta muy
>> protegido
>> > por la clase, creo que el único método que te queda es el const_cast, y
>> aun
>> > así tendrías que hacerlo con una función publica.
>> >
>> > El 9 de marzo de 2010 21:58, Carlos Falgueras García
>> > <fark.zano en gmail.com>escribió:
>> >
>> >> ¡Hola a todos!
>> >>
>> >> Escribo para pediros vuestra opinión sobre el uso de const_cast para
>> >> cambiar el valor de una constante, en concreto un atributo constante de
>> >> una
>> >> clase cualquiera. Se que el valor de los atributos constantes de una
>> clase
>> >> debe pasarse en los inicializadores(no estoy seguro de que se llamen
>> así
>> >> :S) del constructor, pero en mi caso me resulta imposible pues el valor
>> de
>> >> estos lo calculo con un algoritmo complejo.
>> >>
>> >> Os ilustro con un ejemplo sencillo:
>> >>
>> >> class MiClase{
>> >>
>> >> private:
>> >>
>> >> const int atributo_constante;
>> >>
>> >> public:
>> >>
>> >> MiClase(int argumentos) : atributo_constante(0){
>> >>
>> >> int* p = const_cast<int*>(&atributo_constante);
>> >>
>> >>
>> >> //Complejo algoritmo
>> >>
>> >> int aux=0;
>> >>
>> >> aux += argumentos*2;
>> >>
>> >> //Supuesto cambio de valor
>> >> *p=aux;
>> >>
>> >> }
>> >>
>> >> };
>> >>
>> >> He leído en el curso de
>> >> cconclase<http://c.conclase.net/curso/index.php?cap=042#CAS_const>que
>> esto
>> >> puede no cambiar realmente el valor de la constante dependiendo del
>> >> compilador. ¿Es esto siempre así, aún refiriéndonos a un atributo y no
>> a
>> >> una
>> >> clase?
>> >> He comprobado que funciona como se espera en codepad <
>> http://codepad.org>,
>> >> aquí tenéis el link: http://codepad.org/aU9WAXYF
>> >>
>> >> Si la respuesta es que esto es desaconsejable, inútil o "deberías estar
>> >> loco para hacer algo así" , os agradecería que me indicarais si existe
>> >> alguna otra forma de hacer esta asignación;
>> >>
>> >> P.D.: Por supuesto quiero obcecadamente que mi atributo sea constante
>> XD
>> >>
>> >> ¡Muchas gracias de antemano!
>> >>
>> >> _______________________________________________
>> >> Lista de correo Cconclase Cconclase en listas.conclase.net
>> >>
>> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>> >> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>> >>
>> >
>>
>> _______________________________________________
>> Lista de correo Cconclase Cconclase en listas.conclase.net
>> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>>
>
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20100310/d3f98445/attachment.html>


Más información sobre la lista de distribución Cconclase