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

Davidson, Steven srd4121 en njit.edu
Lun Dic 30 18:24:25 CET 2013


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
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20131230/5647ef3e/attachment.html>


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