[C con Clase] En relación a Shared_Ptr y memory leaks

Miguel Ángel Torres Fernández-Píñar miguelangeltorresfp en gmail.com
Lun Dic 30 21:31:09 CET 2013


uf, poco a poco voy entendiendo cosas Steven, muchas gracias por tener
tantísima paciencia.


El 30 de diciembre de 2013, 20:12, Miguel Ángel Torres Fernández-Píñar <
miguelangeltorresfp en gmail.com> escribió:

> Gracias Steven como siempre.
>
> Me quedo asimilando el amplio contenido de tu email.
>
> Feliz año !!!
>
>
> El 30 de diciembre de 2013, 18:24, Davidson, Steven <srd4121 en njit.edu>escribió:
>
>> Hola Miguel Ángel,
>>
>> 2013/12/30 Miguel Ángel Torres Fernández-Píñar <
>> miguelangeltorresfp en gmail.com>
>>
>>> Buenos días Steven.
>>>
>>> Más o menos entiendo la idea. Lo que me cuesta ahora es saberlo aplicar
>>> en la práctica.
>>>
>>> Y me doy cuenta de que lo que me falta es la base.
>>>
>>> No tengo claro cuándo debo definir atributos ( miembros de una clase )
>>> como punteros a objetos ( en este caso con Shared_Ptr ) o como variables de
>>> objetos.
>>>
>>> Si los atributos son definidos como variables de objetos, aunque no lo
>>> haga yo explicitamente, la clase los crea en el constructor, no ???
>>>
>>>
>> Realmente, esos miembros objeto son creados en la lista inicializadora
>> del constructor. Si no existe tal lista inicializadora, entonces justo
>> antes de entrar en el cuerpo de la función (del constructor), los miembros
>> son instanciados en el orden de aparición. Por ejemplo,
>>
>> class B {...};
>>
>> class Algo
>> {
>> private:
>>   string str;
>>   B obj;
>>   int n;
>>
>> public:
>>   Algo()  {}
>> };
>>
>> Esto significa que primero 'str' es instanciado, según su constructor
>> (sin parámetros), luego 'obj'. y por último se crea 'n'.
>>
>> Otro ejemplo, con una lista inicializadora,
>>
>> class B
>> {
>> private:
>>   float f;
>>
>> public:
>>   B( float ff=-1.0f ) : f(ff)  {}
>> };
>>
>> class Algo
>> {
>> private:
>>   string str;
>>   B obj;
>>   int n;
>>
>> public:
>>   Algo() : str("hola mundo"), obj(10.2f), n(1)  {}
>> };
>>
>> En ambos casos, un objeto de 'Algo' guarda estos tres miembros en memoria
>> contigua, por lo que ocupará un mínimo de 12 bytes, dependiendo de lo que
>> ocupen los miembros.
>>
>> Y si son definidos como punteros, entonces puedo crearlos yo cuando y
>>> donde quiera, no ???
>>>
>>>
>> Correcto. Agrego lo que comenté en mis primeras respuestas a tus
>> correos-e, para usar polimorfismo, necesitamos punteros a objetos o
>> referencias a objetos. Personalmente, los punteros son más flexibles, así
>> que aconsejo usarlos para este caso.
>>
>> Otro uso puede ser a la hora de manipular objetos que existan en otra
>> parte de tu programa, por lo que no quieres crear copias. La solución es
>> usando punteros para apuntar a tales objetos. Podrías usar referencias,
>> pero como dije antes, los punteros ofrecen mayor flexibilidad porque existe
>> el puntero nulo mientras que la referencia nula no existe, en C++. Esto
>> viene a ser lo que leíste o te comentaron acerca del uso de 'shared_ptr'.
>> El ejemplo es a la hora de cargar y usar recursos comunes y compartidos,
>> como por ejemplo, imágenes, sonidos, texto, etc.. Por ejemplo,
>>
>> class Imagen {...};
>> class Sonido {...};
>> class Texto {...};
>>
>> class Aplicacion
>> {
>> protected:
>>   Imagen *pImagen;
>>   Sonido *pSonido;
>>   Texto *pTexto;
>>
>> public:
>>   Aplicacion( Imagen *pi, Sonido *ps, Texto *pt ) : pImagen(pi),
>> pSonido(ps), pTexto(pt)  {}
>> };
>>
>> Estamos realizando copias poco profundas, porque sólo queremos apuntar a
>> objetos que ya existan en otra parte.
>>
>> Y no entendí esto :
>>>
>>>
>>> Siempre nos interesa construir el puntero compartido; así que haz esto:
>>>
>>> shared_ptr<int> sp = new int;
>>>
>>> ¿ Con tipos básicos como int también se debe de usar Shared_Ptr ???, es
>>> decir, usar punteros ???.
>>> Porque yo estoy usando constantemente variables de tipo int como
>>> atributos de las diferentes clases que creo. Es decir, no los creo con
>>> "new".
>>>
>>>
>> No debes hacer nada que no quieras :)  Puedes usar un puntero a 'int', si
>> quieres, pero nadie te impone que lo hagas. Lo que puse no era más que un
>> ejemplo, para no tener que crear una clase y usarla en 'shared_ptr'.
>> Personalmente, dudo que vayas a necesitas 'shared_ptr' directamente para un
>> puntero a 'int'. Lo que sí puede ocurrir es usar un 'vector<int>' y
>> posiblemente un puntero a tal clase; por ejemplo,
>>
>> shared_ptr< vector<int> > spvi = new vector<int>;
>>
>> Y supongo que en tal caso sería así, no ???
>>> shared_ptr<int> sp = <shared_ptr>( new int);
>>>
>>>
>> Como mencioné en mi correo-e anterior, esto sería,
>>
>> shared_ptr<int> sp = new int;
>>
>> El problema de este ejemplo es que no es muy práctico. No hacemos mucho
>> con un puntero a un solo 'int'; convendría una lista de 'int'.
>>
>> En fin, Steven, no te preocupes mucho, supongo que necesito tiempo para
>>> irme aclarando con todo esto.
>>>
>>
>> Esto tiene que ver con los usos prácticos de los punteros. Las
>> plantillas-clase que comenté en el correo-e anterior sirven para
>> automatizar el uso del puntero y protegerlo a través del uso de un objeto.
>> No tienes por qué usar 'shared_ptr' ni las demás plantillas si no quieres.
>>
>>
>> Espero que esto te oriente.
>>
>> Steven
>>
>>
>> _______________________________________________
>> 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/20131230/a532ecc8/attachment.html>


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