在构造函数中调用的成员变量的析构函数 - 编译器错误?

时间:2012-10-17 10:50:54

标签: c++ visual-studio visual-studio-2012

我遇到了Visual Studio 2012的问题。首先是SSCCE:

class CacheImpl
{
public:
    float* m_cache;

    CacheImpl()
    {
        m_cache=(float*)new float[1];
    }

    ~CacheImpl()
    {        
        delete [] m_cache;
    }
};

class Image 
{
public:
    Image() {}
    ~Image() {}
};

static const Image g_tmpImg;

class Filter
{       

public:

    Filter() : m_img(Image())
    //Filter() : m_img(g_tmpImg) // <-- This variant works
    {
        //Empty
    }

private:

    CacheImpl m_cache;
    const Image &m_img;
};

int main()
{
    Filter f;
    return 0;
}

当运行它(在调试模式下编译)时,我在CacheImpl中删除了CRT断言,查看Filter()的汇编列表或在~CacheImpl()中设置断点显示~CacheImpl()正在在没有明显原因的情况下在Filter构造函数的末尾调用(事实上,这在VS2010中不会发生)。而是为临时对象调用了Image(),VS2012

在VS2012中进行编译时,我收到警告“C4413:'Filter :: m_img':引用成员被初始化为一个在构造函数退出后不会持久化的临时成员”。我理解这一点,但我希望悬挂参考,而不是崩溃,因为错误的对象正在被破坏。我偶然发现了一个编译器错误,或者我应该接受这个未定义的行为而不是初始化对temporaries的引用?对于上下文,在我的实际代码中,当使用这样的构造函数创建Filter时,永远不会使用悬空引用。

1 个答案:

答案 0 :(得分:0)

有人可能会认为这是一个编译器错误 - 但“未定义的行为”本质上意味着“任何事情都会发生”并且您将对即将被销毁的对象存储的引用限定为未定义的行为。所以你应该接受这个并停止用临时文件初始化引用。