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

Destructor of member variable called in constructor - compiler bug?

本文关键字:成员 变量 驱动器 调用 构造函数 编译器 错误      更新时间:2023-10-16

我在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()正在在过滤器构造函数的末端打电话给出了没有明显原因(实际上,这在VS2010中并没有发生)。而是为临时对象调用〜image(),vs2012 do。

在VS2012中编译此版本时,我会收到警告" C4413:'Filter :: M_img':参考成员的初始化为临时性,该临时性在构造函数退出后不持续不存在"。我理解这一点,但我希望有一个悬而未决的参考,而不是崩溃,因为错误的对象正在破坏。我是否偶然发现了编译器错误,还是应该接受它是不确定的行为而不是初始化对临时性的引用?对于上下文,在我的真实代码中,当使用这样的构造函数创建过滤器时,永远不会使用悬空参考。

有人可能会说这是一个编译器错误 - 但"未定义的行为"本质上意味着"任何事情都会发生",而您很快就将对对象的引用存储为不确定的行为有资格。因此,您应该接受这一点,并停止使用临时引用初始化参考。