【问题标题】:Initializing a static pointer in C++在 C++ 中初始化静态指针
【发布时间】:2012-05-24 03:01:29
【问题描述】:

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

动画.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 函数。 setter 应该使用第二种方法,因为 'x' 将进入一个参数,所以我被卡住了。

感谢您的帮助!

【问题讨论】:

    标签: c++ pointers static initialization


    【解决方案1】:

    我打赌它不会在那条线上崩溃,而是在之后。

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

    就像下面这样是非法的:

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

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

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

    【讨论】:

    • *(Animation::m) = x; 引用 0 指针。指针从未分配,它只是初始化为 0
    • 如果它之前被分配给一个有效的QString*你确定这是正确的吗?
    • @Als 我是,直到你问这个问题 :)) 就像 - 这是我们可以使用的最有效的算法吗?... -嗯,直到现在我都这么认为!
    【解决方案2】:

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

    如果您想使用 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 点仍然存在。

    【讨论】:

      【解决方案3】:

      第二种方法有什么问题?

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

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

      怎么做?

      您应该动态分配内存,然后将字符串复制到动态分配的指针,以便您能够在任何地方访问它。这样,除非明确地deleteed,否则字符串仍然有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-08
        • 2017-08-26
        • 2010-10-16
        • 1970-01-01
        • 2013-05-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多