【问题标题】:Const parameter at constructor causes stackoverflow构造函数中的 const 参数导致 stackoverflow
【发布时间】:2010-05-29 08:49:24
【问题描述】:

我在 VS2005 C++ 编译器中发现了这种奇怪的行为。情况如下:

我无法发布代码,但情况很简单。

这里是初始代码:完美运行

class Foo {
     public:
     Foo(Bar &bar) { ... }
}

构造函数实现存储一个引用,设置一些成员......确实没什么特别的。

如果我按以下方式更改代码:

class Foo {
     public:
     Foo(const Bar &bar) { ... }
}

我在唯一的构造函数例程参数中添加了一个 const 限定符。

它编译正确,但是编译器输出一个警告说例程 Foo::Foo 将导致堆栈溢出(即使执行路径没有构造任何对象 Foo);这实际上发生了。

那么,为什么没有 const 参数的代码可以完美运行,而带有 const 限定符的代码会导致堆栈溢出?什么会导致这种奇怪的行为?

【问题讨论】:

  • 您需要同时发布您收到的代码和编译器警告。
  • 无法用这些信息来判断。我们需要更多信息或可以重现警告的最少代码
  • 真的吗?我有带有 C++ 编译器版本 15.00.30729.01 的 VS2005,并且两个代码 sn-ps(使用 class Bar {};)都没有给我任何堆栈溢出警告,即使在最高警告级别也是如此。我错过了什么吗?
  • 接下来几天我会发布一个引发错误的sn-p。重现相同的运行时错误需要一些时间。
  • 每次遇到此类错误时都执行此操作。 非常将代码简化为重现错误的小示例很可能会告诉您您做错了什么。如果没有,您有一段完美的代码可以在这里发布并询问。

标签: c++ constructor stack-overflow constants


【解决方案1】:

尝试使用explicit 关键字?

我的猜测是,使用const,您正在声明从 Bar 到 Foo 的自动转换;如果您已经有任何类似的从 Foo 到 Bar 的自动转换,那么会溢出吗?

【讨论】:

    【解决方案2】:

    导致堆栈溢出的唯一方法是Foo(const Bar&) 创建一个 Foo 对象传递给它一个 Bar 对象。通过查看代码,此类错误可能很微妙且难以发现。

    但是如果你有 VS2005,你手头就有一个相当不错的调试器。在该构造函数中放置一个断点,运行程序直到遇到断点,然后再次运行,直到第二次遇到断点。检查堆栈将向您展示它是如何发生的。

    如果不是每次调用这个构造函数都会导致堆栈溢出,你可以添加这个代码:

    namespace { unsigned int recursion_detector = 0; }
    
    Foo::foo(const Bar& bar)
    {
      if(recursion_detector++)
        ++recursion_detector; // meaningless code just to put a breakpoint here
      // rest of constructor code
    }
    

    并在指示的行上放置一个断点,当递归发生时将触发该断点。

    【讨论】:

      【解决方案3】:

      您可以将参数从 const Bar &bar 更改为 const Bar *bar。 它可以正常工作,您只需要更改管理参数栏的方式(从引用到指针)。

      对象初始化类似于:

      Bar mybar;
      
      ...
      
      Foo myfoo(&mybar);
      
      
      class Foo {
           public:
           Foo(const Bar *bar) { ... }
      };
      

      没那么糟……

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多