c++多重继承方法重载

C++ multiple inheritance method overloading

本文关键字:重载 方法 多重继承 c++      更新时间:2023-10-16
#include <iostream>
using namespace std;
class Base1 {
public:
    virtual void f(int n) = 0;
};
class Base2 {
public:
    virtual void f(char *s) = 0;
};
class Derive1 : public Base1, public Base2 {
public:
    void f(int n) { cout << "d1 fn" << endl; }
    void f(char *s) { cout << "d1 fs" << endl; }
};
class Derive2 : public Derive1 {
public:
    void f(int n) { cout << "d2 fn" << endl; }
    void f(char *s) { cout << "d2 fs" << endl; }
};
int main() {
    Derive1 *d1 = new Derive2();
    int n = 0;
    char *s = "";
    d1->f(n);
    d1->f(s);
    return 0;
}

上面的代码按预期运行,但是如果我注释掉了Derive1的一个方法,我得到了转换错误;如果我注释掉了Derive1的两个方法,就会得到方法歧义错误。

让我困惑的是,为什么Derive1必须定义这两个方法,为什么只在Derive2中定义它们是不工作的。我需要一些帮助来理解这件事。

一些澄清:

  1. 假设我从来不想创建任何Derive1的实例。所以,如果Derive1是一个抽象类是完全可以的。

  2. "所有纯虚函数都应该在派生类中有定义。"如果我不想创建这个派生类的实例,这是不正确的。

  3. 如果我将Base1中的f更改为f1, Base2中的f更改为f2(只是更改名称),那么Derive1不需要定义它们中的任何一个,只需在Derive2中定义f1和f2即可。

所以,在方法重载的支持下,我认为,在上面的代码中,我声明了一个函数,名字类似于Base1中的f_int;在Base2中,我声明了一个名为f_str的函数。这就是编译器实现方法重载的方式,对吧?但事实似乎并非如此。

Derive1Base1Base2的派生类。派生类必须实现其基类的所有虚函数。

Derive2实现这些函数对Derive1没有帮助,因为可以实例化Derive1,并且必须实现所有继承的纯虚方法。

例如,如果你没有实现Derive1中的函数,你会期望它的行为是什么?

Derive1* d1 = new Derive1;
int n = 0;
char *s = "";
d1->f(n);
d1->f(s);

Derive1没有实现这些,d1不是Derive2实例,所以它应该做什么?

如果你在一个类中声明一个纯虚函数,它将变成一个抽象类,你不能实例化它。所有纯虚函数都应该在派生类中有定义。你的两个基类都有纯虚函数,所以你的派生类应该定义基类的纯虚函数。

让我们从移除Derived1:

开始

当您调用d1->f时,您没有为该类创建任何特定的内容,因此它查找其基类。每个基类将被视为一组单独的候选类。因此,它首先检查base1并看到一个f,然后检查base2并看到另一个f。编译器不能选择调用哪一个,所以调用是二义性的。如果你不想重新实现父函数,你可以将它们using放入Derived1,或者给编译器一个关于使用哪个基的提示。

如果您只注释掉Derived1中的一个函数,那么您留下的将隐藏两个父版本,防止其中任何一个被选中。此时,您可以调用已定义的那个,而不能调用另一个,除非您再次告诉编译器您希望从哪个特定的基类调用它。