c++多重继承方法重载
C++ multiple inheritance method overloading
#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中定义它们是不工作的。我需要一些帮助来理解这件事。
一些澄清:
假设我从来不想创建任何Derive1的实例。所以,如果Derive1是一个抽象类是完全可以的。
"所有纯虚函数都应该在派生类中有定义。"如果我不想创建这个派生类的实例,这是不正确的。
如果我将Base1中的f更改为f1, Base2中的f更改为f2(只是更改名称),那么Derive1不需要定义它们中的任何一个,只需在Derive2中定义f1和f2即可。
所以,在方法重载的支持下,我认为,在上面的代码中,我声明了一个函数,名字类似于Base1中的f_int;在Base2中,我声明了一个名为f_str的函数。这就是编译器实现方法重载的方式,对吧?但事实似乎并非如此。
Derive1
是Base1
和Base2
的派生类。派生类必须实现其基类的所有纯虚函数。
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
中的一个函数,那么您留下的将隐藏两个父版本,防止其中任何一个被选中。此时,您可以调用已定义的那个,而不能调用另一个,除非您再次告诉编译器您希望从哪个特定的基类调用它。
- 重载方法的方式会在使用临时调用时生成编译器错误
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 一种优雅或至少可行的方法,用于使用和接受具有重载方法和运算符的不同大小的文字数组常量
- 使用 nullptr 调用重载方法是不明确的
- 具有重载方法的可变参数数据结构
- C++11 重载方法,并转发到唯一方法
- 获取特定的模板重载方法指针
- std::result_of 应用于 const 重载方法
- 重载方法的类接受模板和基类 - 如何默认某个方法
- 推导模板类重载方法的地址会导致"error: expected primary-expression before ‘decltype’"
- C++如何使用按值传递和按引用传递的重载方法
- 具有原始方法参数派生类的 C++ 重载方法参数
- SWIG:在派生类中处理基类重载方法
- 在c++中的赋值运算符重载方法中删除旧的动态分配内存
- C++选择'wrong'默认参数的重载方法
- 重写重载方法会隐藏一些重载
- 在C++中,如何从父类变量的子类调用重载方法
- 所有重载方法的别名
- 使用 SWIG 在重载C++方法中设置类型