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
的预期值。
我认识到按值传递和按常量引用传递之间存在差异。但是,就我而言,我不认为存在实际差异。
用 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
的预期值。
我认识到按值传递和按常量引用传递之间存在差异。但是,就我而言,我不认为存在实际差异。