2012-05-16 16 views
7

que tienen una clase con un miembro estático que es un puntero de este modo:La inicialización de un puntero estática en C++

animation.h

class Animation 
{ 
public: 
    Animation(); 
    static QString *m; 

}; 

animation.cpp

#include "animation.h" 

QString* Animation::m = 0; 

Animation::Animation() 
{ 
} 

Cuando intento para inicializar ese puntero 'm' de otra clase como ese:

Animation::m = new QString("testing"); 

Funciona.

Pero cuando lo hago de esta manera:

QString x("Testing"); 
Animation::m = &x; 

El programa falla.

¿Qué hay de malo con este segundo método?

También me gustaría tener ese puntero estático como privado, así que puedo hacer funciones fijas de captador y definidor. El colocador debe usar el segundo método ya que la 'x' vendrá en un parámetro, así que estoy atascado.

¡Gracias por cualquier ayuda!

Respuesta

12

Apuesto a que no está fallando en esa línea, sino después.

El problema es que está tomando la dirección de una variable ubicada en la memoria automática, y probablemente intente acceder a ella después. La variable x se destruirá cuando termine el alcance, pero Animation::m seguirá apuntando a esa memoria (la memoria que ya no posee después de x salió del alcance). Esto da como resultado comportamiento indefinido.

Al igual que el siguiente sería ilegal:

int* x = NULL; 
{ 
    int k = 3; 
    x = &k; 
} 
*x = 4; 

Solución asignar al valor, no el puntero (siempre que fue asignado previamente a un válido QString*):

QString x("Testing"); 
*(Animation::m) = x; 
+0

¡Eso definitivamente lo responde gracias! –

+0

'* (Animation :: m) = x;' deferences un puntero '0'. El puntero nunca fue asignado, se acaba de inicializar a' 0'. –

+0

@Als se perdió, se corrigió. Gracias. –

2

¿Qué está mal con este segundo método?

Se bloquea porque es muy probable que acceda más allá del alcance en el que se creó x.

Las variables automáticas se destruyen automáticamente una vez que el control sale del alcance {} en el que se crearon, por lo que lo que tiene es un puntero que apunta a datos que no existen. El acceso a estos datos causa un comportamiento indefinido y un bloqueo.

¿Cómo proceder?

Debe asignar dinámicamente memoria y luego copiar la cadena al puntero asignado dinámicamente para que pueda acceder a ella en cualquier lugar. De esta manera, la cadena sigue siendo válida a menos que explícitamente delete ed.

1

Apuesto a que su programa se bloquea cuando usa Animation::m después de que se destruye x (probablemente al salir del alcance).

Si desea utilizar un regulador de asignar a Animation::m, tendrá que pasar en el argumento como un puntero o por referencia:

class Animation 
{ 
public: 
    Animation(); 

    void set_m(QString* ptr) { 
     m = ptr; 
    } 

    void set_m(QString& ref) { 
     m = &ref; 
    } 

private: 
    static QString *m; 

}; 

Sin embargo, usted todavía necesita para asegurarse de que lo que sea m puntos todavía está vivo cuando intenta utilizar m.

Cuestiones relacionadas