如何在多重继承中调用超类方法?

Posted

技术标签:

【中文标题】如何在多重继承中调用超类方法?【英文标题】:How to call superclass method in multiple-inheritance? 【发布时间】:2020-10-27 15:24:00 【问题描述】:

我有一个类C,它继承自AiBAB 不相关。下面的代码可以很好地解释这一切。在main() 中,我有一个变量a 定义为std::unique_ptr<A>,但使用C 进行了初始化。我不能改变这个定义。

我的问题是,鉴于a 的定义是这样的,我该如何正确调用BCAi 中定义的函数?

#include <memory>

class A 
 
public: 
  void fun_a() 
; 
  
class B 
 
public: 
  void fun_b() 
; 

class Ai : public A
 
public:
    void fun_ai() 
; 
  
class C: public Ai, public B
 
public:
    void fun_c() 
; 
  
int main() 
 
    // I cannot change the following definition:
    std::unique_ptr<A> a = std::make_unique<C>();
    
    a->fun_a();
    //a->fun_b(); // How ?
    //a->fun_c(); // How ?
    //a->fun_ai(); // How ?
    
    return 0; 

【问题讨论】:

一个词:向下转型。 这能回答你的问题吗? "Downcasting" unique_ptr<Base> to unique_ptr<Derived> 【参考方案1】:

您可以将static_cast 转为C*

static_cast<C*>(a.get())->fun_b();
static_cast<C*>(a.get())->fun_c();
static_cast<C*>(a.get())->fun_ai();

或者你可以让它成为多态的:

class A  
public: 
    virtual ~A() = default;
    void fun_a()  std::cout << "fun_a\n"; 
;

然后dynamic_cast:

dynamic_cast<B*>(a.get())->fun_b();
dynamic_cast<C*>(a.get())->fun_c();
dynamic_cast<Ai*>(a.get())->fun_ai();

注意:dynamic_casts 指向指针类型可能会失败并返回nullptr,因此,如果有任何疑问,请检查返回值。

Demo

【讨论】:

如果您使用基类指针来寻址派生类实例,那么原则上链中的所有类肯定都应该包含虚拟析构函数吗? @Den-Jason 只有当实例通过B* 销毁时,我才能看到问题(而且我没有看到这种情况发生)。其余的析构函数已经自动成为virtual。嗯,想想看,就算被B*毁了也行吧。 和(更清楚一点)wiki.sei.cmu.edu/confluence/display/cplusplus/… @Den-Jason 是的,A 应该有一个 virtual 析构函数,因为 C 正在通过 A* 销毁。现在,OP:s 类没有任何成员变量或虚拟方法,所以我不确定它是否是 UB。反正也不好看:) @N.R.太好了,不客气!当您可能需要通过基类指针销毁某些东西时(如本例所示),请创建基类析构函数virtual。虽然没有 virtual 构造函数这样的东西。

以上是关于如何在多重继承中调用超类方法?的主要内容,如果未能解决你的问题,请参考以下文章

Python基础编程——多重继承下方法的调用

多重继承

Python 多重继承:选择要调用的基类方法

----特质

用多重继承调用父类__init__,正确的方法是啥?

Doctrine 2 多重映射继承