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

如何在一个派生类中调用另一个派生类的成员函数?

如何在派生类中调用另一个派生类的重写成员函数?

你的核心需求是在D2::A()中执行自身逻辑后,复用D1::A()的实现以消除代码重复。首先纠正原代码的基础问题:D1和D2需要改为public继承BASE,否则基类指针无法正确指向派生类对象,原代码中的BASE *b = &d1会因private继承触发编译错误。

以下是几种可行的解决方案:

方案1:提取非虚的实现函数(推荐)

把D1::A()的核心逻辑抽离成非虚辅助函数,让D2可以直接调用该函数,不会触发多态:

#include <iostream>

class BASE 
{
public:
  virtual ~BASE() = default;
  virtual void A() { std::cout << "In BASE\n"; }
  virtual void B() { std::cout << "Shared by all instances\n"; }
  virtual void C() { std::cout << "Different in all instances\n"; }
};

class D1: public BASE  // 改为public继承
{
public:
  void A() override { A_impl(); }
  // 提取非虚的核心实现
  void A_impl() { std::cout << "In D1\n"; }
  void C() override { std::cout << "In D1::C()\n"; }
};

class D2: public BASE  // 改为public继承
{
public:
  void A() override
  {
     std::cout << "In D2\n";
     // 直接调用D1的非虚实现函数
     D1::A_impl();
  }
  void C() override { std::cout << "In D2::C()\n"; }
};

int main()
{ 
  D1 d1;
  D2 d2;

  BASE *b = &d1;
  b->A();  // 输出:In D1

  b = &d2;
  b->A();  // 输出:In D2\nIn D1
}

这种方式既保留了多态特性,又能安全复用D1的逻辑,是最简洁的解决方案。

方案2:创建D1对象调用其成员函数

如果D1::A()的逻辑不依赖对象状态,可以直接创建临时D1对象调用:

void A() override
{
   std::cout << "In D2\n";
   D1 temp;
   temp.A();  // 调用D1的A()实现
}

但如果D1::A()需要依赖特定的对象状态,这种方式就不适用,因为临时对象的状态和当前D2对象无关。

原有尝试失败的原因

  • #1错误:D1::A()是非静态成员函数,必须通过对象实例调用,直接用类名调用不符合C++语法规则,因此编译报错。
  • #2错误:强制将this转换为D1*后,t->A()仍然会触发多态调用——因为this实际指向的是D2对象,虚函数表中A()的地址还是D2::A(),最终导致无限递归。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:44:59