如何在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
相关产品推荐
相关产品推荐

