【发布时间】:2012-10-17 10:50:53
【问题描述】:
我在使用 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 没有这样做。
在 VS2012 中编译它时,我收到警告“C4413:'Filter::m_img':引用成员被初始化为一个临时的,在构造函数退出后不会持续存在”。我理解这一点,但我期望一个悬空引用,而不是崩溃,因为错误的对象正在被破坏。我是否偶然发现了编译器错误,还是应该将其视为未定义的行为而不初始化对临时对象的引用?对于上下文,在我的真实代码中,当使用这样的构造函数创建 Filter 时,从不使用悬空引用。
【问题讨论】:
-
Rule of Zero:使用
std::vector。 -
是的,但这不是重点。内存分配只是为了暴露双重破坏。
-
@R.MartinhoFernandes 仍然与实际问题没有任何关系。但是感谢这个漂亮的标语,以前没听过。
-
另一方面:C-Cast 不是必需的。
m_cache=(float*)new float[1];在任何 C++ 代码中都不是一个好主意。 -
绝对看起来像一个错误。我会报告的。请注意,颠倒成员的顺序可以解决问题。
标签: c++ visual-studio visual-studio-2012