Инициализация статического указателя в 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;
что не так с этим второй способ ?
он падает, потому что вы, скорее всего, получите доступ к нему за пределами области, в которой .
автоматические переменные автоматически уничтожаются после выхода элемента управления из области {
}
в котором они были созданы, поэтому за пределами области у вас есть указатель, указывающий на данные, которые не существуют. Доступ к этим данным вызывает неопределенное поведение и сбой.
как заняться этим?
вы должны динамически выделять память, а затем копировать строку в динамически выделенный указатель, чтобы вы могли получить к ней доступ везде. Таким образом, строка остается действительной, если и до тех пор, пока явно delete
ed.
держу пари, что ваша программа аварийно завершает работу, когда вы используете 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
.