在C ++中初始化静态指针

时间:2012-05-16 14:12:11

标签: c++ pointers static initialization

我有一个带有静态成员的类,它是一个像这样的指针:

animation.h

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

};

animation.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 个答案:

答案 0 :(得分:13)

我打赌它并没有在那条线上崩溃,而是之后。

问题是您正在获取位于自动内存中的变量的地址,并可能在之后尝试访问它。变量x将在其范围结束时被销毁,但Animation::m仍将指向该内存(x超出范围后您不再拥有的内存)。这会导致未定义的行为

就像以下情况一样:

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

解决方法分配给值,而不是指针(前提是它先前已分配给有效的QString*):

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

答案 1 :(得分:2)

第二种方法出了什么问题?

崩溃是因为您最有可能在创建x的范围之外访问它。

一旦控件退出创建它们的范围{ },自动变量就会自动销毁。因此,除了范围之外,指针指向不存在的数据。访问此数据会导致未定义的行为和崩溃。

如何解决?

您应该动态分配内存,然后将字符串复制到动态分配的指针,以便您可以在任何地方访问它。这样字符串保持有效,除非明确地delete编辑。

答案 2 :(得分:1)

我敢打赌,在Animation::m被销毁之后使用x时,你的程序会崩溃(可能超出范围)。

如果要使用setter分配给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点仍然存在。