C++ / 按值传递导致#DEN

C++ / Pass by value results in #DEN

用 Visual Studio 调试一些代码,我惊讶地发现一个对象的 属性 的值在调用方法之前看起来很好,然后在我进入时就被破坏了方法:

电话是从这里来的。调试器报告 thingA.property = 0.14

method1()
{
  Thing thingA;

  object.method2(thingA)
}

并进入此处,调试器报告 thingMine.property = 4.0E-315#DEN

method2(Thing thingMine)
{
....
}

当我将范围改回 method1 时,属性 看起来不错,而范围缩小到 method2 时,属性 呈现出截然不同的值。

什么会导致值发生变化?回到使用 C 的 过去 时代,我可以通过摆弄指针来破坏内存。然而,这段代码并没有什么特别之处。没有(明确的)指针。编译器对所有对象的转换/class 感到满意。没有花哨的继承或重载。

要添加更多细节,Thing 不仅仅是具有属性和方法的 class。它的属性是对象,但仍然不是很花哨:

class Thing {
public:
  AnotherThing thingInsideAThing;
...
}

AnotherThing 的 属性 被破坏了。

我对 按值传递 的理解是基于我在 C 中的古老教育。我认为调用方法会将 thingA 的显式副本推送到堆。它是否将 thingA.object 的错误地址压入堆栈?我认为 按值传递 始终 将信息转发到方法中的最安全方式。

我从哪里开始了解根本问题?

我相信 Visual Studio 显示

对象值的方式可以找到答案
  • 按值传递
  • 通过常量引用传递

下面的代码将正确的值分配给 a。但是,对于我的对象,调试器在我要求它显示 thing.x.

时报告 #DEN
method(Thing thing)
  {
    double a = thing.x;
  }

然而,当我写:

method(const Thing& thing)
  {
    double a = thing.x;
  }

调试器报告 thing.x 的预期值。

我认识到按值传递按常量引用传递之间存在差异。但是,就我而言,我不认为存在实际差异。