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

按引用传递会生成副本吗?子类对象传入父类引用参数是否产生临时拷贝?

关于C++引用传递是否产生副本的问题解答

嘿,这个问题问到点子上了!刚好能帮你理清C++里引用、继承和多态的核心细节,咱们一步步说:

核心结论:按引用传递不会产生对象副本

引用在C++里本质就是原对象的"别名",它直接绑定到你传入的对象上,操作引用就等同于操作原对象本身,不会额外创建临时对象或者副本——这也是引用传递相比值传递更高效的原因之一。

针对你给出的继承场景详细解释

你提到的场景:类B继承自A,方法void sum(A &val)接收A类型的引用,传入B对象b调用sum(b)——这种情况完全不会创建b的临时副本。

用代码验证一下

咱们写个实际的例子,直观看看效果:

#include <iostream>
using namespace std;

class A {
public:
    int base_val = 10;
    // 加虚函数方便看多态效果
    virtual void show_info() {
        cout << "这是A类对象,base_val: " << base_val << endl;
    }
};

class B : public A {
public:
    int derived_val = 20;
    void show_info() override {
        cout << "这是B类对象,base_val: " << base_val << ", derived_val: " << derived_val << endl;
    }
};

void sum(A &val) {
    // 修改引用绑定的对象的成员变量
    val.base_val = 100;
    // 调用虚函数,看实际调用的是哪个类的版本
    val.show_info();
}

int main() {
    B b;
    cout << "调用sum函数前:";
    b.show_info();
    
    sum(b); // 传入B对象到A类型引用参数
    
    cout << "调用sum函数后:";
    b.show_info();
    return 0;
}

运行结果和分析

输出结果会是:

调用sum函数前:这是B类对象,base_val: 10, derived_val: 20
这是B类对象,base_val: 100, derived_val: 20
调用sum函数后:这是B类对象,base_val: 100, derived_val: 20

从结果能看出来:

  1. sum函数里修改val.base_val后,原对象b的base_val也变成了100——说明操作的是原对象,没有副本。
  2. sum里调用val.show_info()时,执行的是B类的版本——说明引用绑定的还是完整的B对象,只是通过A类型的引用只能访问基类的成员(但对象本身的类型没变)。

对比值传递的情况(为什么会混淆?)

如果sum的参数是值传递:void sum(A val),那传入B对象时就会发生切片——创建一个A类型的副本,只复制B对象里属于A的部分,此时操作的是副本,原对象不会被修改,而且show_info()会调用A的版本。但你的例子是引用传递,完全不会有这个问题。

最后再划个重点

  • 只要是引用传递(不管是基类引用还是派生类引用),都不会创建对象副本,直接绑定原对象。
  • 派生类对象绑定到基类引用是C++多态实现的基础,安全且高效,不会触发切片行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:39:57