You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

显式解引用指针以引用传递时编译器层面的行为探究

显式解引用指针并传引用给函数时的编译器行为分析

先看第一个代码片段的行为:

void foo(A& arg)
{
   arg.member = 7;
}

void goo()
{
   A* ob = new A();
   foo(*ob);
   printf(ob->member); // 应该输出7
}

对指针ob执行解引用操作*ob后,得到的是堆上A对象的左值。当把这个值传给接受A&类型参数的foo函数时,函数形参arg会直接绑定到堆上的原对象。因此在foo中修改arg.member,本质就是直接修改原对象的成员变量,最后通过ob->member访问时,自然会得到修改后的7。

再看第二个代码片段,两者的核心差异出现在解引用的时机和用途上:

void foo(A& arg)
{
   arg.member = 7;
}

void goo()
{
   A* ob = new A();
   A ob_dereferenced = *ob;
   foo(ob_dereferenced);
   printf(ob->member); // 应该输出A初始化member的默认值
}

这里A ob_dereferenced = *ob;并不是创建原对象的引用,而是通过拷贝构造函数创建了一个全新的栈上对象,这个对象是堆上原对象的副本。之后调用foo(ob_dereferenced)时,形参arg绑定的是这个栈上的副本,所有修改操作都只作用于副本,堆上的原对象完全不受影响。所以最后printf输出的还是原对象初始化时的member值。

总结两者的核心区别:

  • 直接传*ob给foo:解引用结果直接作为引用绑定到原对象,操作的是原对象本身
  • 先赋值给ob_dereferenced再传参:解引用触发拷贝构造,生成独立副本,后续操作与原对象无关

内容的提问来源于stack exchange,提问作者Omroth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:52:07