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

如何在C++子类中调用父类的operator=或析构函数?

问题解答

一、当前B和C的实现问题

1. 析构函数实现错误

  • B的析构函数中手动执行delete [] name会触发双重释放:由于基类A的析构函数是虚函数,销毁B对象时会先执行B的析构函数,再自动调用A的析构函数,而A的析构函数已经会释放name,两次释放同一块堆内存属于未定义行为。
  • C的析构函数存在同样问题:delete [] name与基类析构的重复释放会导致错误,不过delete [] c是正确的(c是C类新增的堆成员)。

2. 赋值运算符(operator=)实现冗余

  • B和C的operator=中都重复编写了基类成员name的赋值逻辑(delete [] name; name = new char[10]; strcpy(name, rhs.name);),这部分代码与基类A的operator=完全一致,属于冗余代码。后续如果基类A对name的处理逻辑修改(比如调整数组大小、改用std::string),子类需要同步修改,维护成本高。
  • 从功能上看,当前B和C的operator=能完成同类型对象的赋值,但代码复用性差。

二、优化方案:复用基类逻辑

1. 析构函数的修正

子类不需要手动处理基类的堆成员name,直接删除子类析构函数中delete [] name的代码即可。虚析构函数的调用链会自动触发基类析构,完成name的释放:

  • B的析构函数可简化为:
virtual ~B() {
    // 无需手动释放name,基类析构会自动处理
}

甚至可以完全省略子类析构函数,编译器会生成默认的虚析构函数,同样会触发基类析构流程。

  • C的析构函数只需保留自身新增成员c的释放:
virtual ~C() {
    delete [] c;
}

2. 赋值运算符的优化:调用基类operator=

在子类的operator=中,直接调用A::operator=(rhs)复用基类的name赋值逻辑,避免重复代码:

  • B的operator=优化后:
virtual B& operator=(const B& rhs) {
    if (this == &rhs) {
        return *this;
    }
    // 调用基类赋值运算符处理name
    A::operator=(rhs);
    // 处理自身成员b
    b = rhs.b;
    return *this;
}
  • C的operator=优化后:
virtual C& operator=(const C& rhs) {
    if (this == &rhs) {
        return *this;
    }
    // 调用基类赋值运算符处理name
    A::operator=(rhs);
    // 处理自身堆成员c
    delete [] c;
    c = new int[10];
    for (int i = 0 ; i < 10 ; i++) {
        c[i] = rhs.c[i];
    }
    return *this;
}

这样既保证了逻辑正确性,又减少了冗余代码,提升了代码的可维护性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:24:50