Инициализация статического указателя в C++

у меня есть класс со статическим членом, который является указателем так:

анимация.h

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

};

анимация.cpp

#include "animation.h"

QString* Animation::m = 0;

Animation::Animation()
{
}

когда я пытаюсь инициализировать этот указатель " m " из другого класса, например:

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

это работает.

но когда я делаю это так :

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

программа аварийно завершает работу.

что не так с этим второй способ ?

также я хотел бы иметь этот статический указатель как частный, поэтому я могу сделать статические функции getter и setter для него. Сеттер должен использовать второй метод, так как " x " будет входить в параметр, поэтому я застрял.

Спасибо за любую помощь!

3 ответов


Я уверена, что это не сбой на этой линии, но потом.

проблема в том, что вы берете адрес переменной, расположенной в автоматической памяти, и, вероятно, пытаетесь получить к ней доступ впоследствии. Переменная x будет уничтожен, когда это область заканчивается, но Animation::m будет по-прежнему указывать на эту память (память, которой вы больше не владеете после x вышел за рамки). Это приводит к неопределенное поведение.

, как в следующем будет незаконно:

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

решение назначить значение, а не указатель (при условии, что он был ранее назначен действительному QString*):

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

что не так с этим второй способ ?

он падает, потому что вы, скорее всего, получите доступ к нему за пределами области, в которой .

автоматические переменные автоматически уничтожаются после выхода элемента управления из области { } в котором они были созданы, поэтому за пределами области у вас есть указатель, указывающий на данные, которые не существуют. Доступ к этим данным вызывает неопределенное поведение и сбой.

как заняться этим?

вы должны динамически выделять память, а затем копировать строку в динамически выделенный указатель, чтобы вы могли получить к ней доступ везде. Таким образом, строка остается действительной, если и до тех пор, пока явно deleteed.


держу пари, что ваша программа аварийно завершает работу, когда вы используете Animation::m после x был уничтожен (вероятно, выйдя из области видимости).

если вы хотите использовать сеттер назначить Animation::m, вам нужно будет передать аргумент в качестве указателя или по ссылке:

class Animation
{
public:
    Animation();

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

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

private:
    static QString *m;

};

тем не менее, вам все равно нужно убедиться, что все m очки все еще живы, когда вы пытаетесь использовать m.