#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中定义它们不起作用。我需要一些帮助才能理解这一点。
一些澄清:
因此,在方法重载的支持下,我想,在上面的代码中,我声明了一个函数,其名称类似于f_int in Base1;在Base2中,我声明了一个名称类似于f_str的函数。这就是编译器实现方法重载的方式,对吗?但情况似乎并非如此。
发布于 2015-05-22 14:47:09
Derive1是从Base1和Base2派生的类。派生类必须实现其基类的所有纯虚拟函数。
Derive1实现这些函数无助于Derive2,因为实例化Derive1是可能的,并且必须实现所有继承的纯虚拟方法。
例如,如果您没有在Derive1中实现这些函数,那么您会期望这种行为是什么呢?
Derive1* d1 = new Derive1;
int n = 0;
char *s = "";
d1->f(n);
d1->f(s);Derive1没有实现这些,d1也不是Derive2实例,那么它应该做什么呢?
发布于 2015-05-22 14:53:18
如果在一个类中声明一个纯虚拟函数,它将变成一个抽象类,并且无法实例化该类。并且所有纯虚拟函数都应该在派生类中有一个定义。您的两个基类都有纯虚拟函数,因此您的derived1应该定义基类的纯虚拟函数。
发布于 2015-05-22 19:09:07
让我们从在Derived1中删除这两者开始
当您调用d1->f时,您还没有创建任何特定于该类的内容,因此它看起来是它的基类。每个基类将被视为一组单独的候选人。因此,它首先检查base1并看到一个f,然后检查base2并看到另一个f。编译器无法选择要调用哪一个,因此调用是不明确的。如果不想重新实现父函数,或者向编译器提示使用哪个基,可以将父函数using到Derived1中。
如果您只注释掉了Derived1中的一个函数,那么您留下的函数会隐藏两个父版本,从而阻止选择其中的一个。此时,您可以调用已定义的类,也不能调用另一个类,除非再次告诉编译器要从哪个特定的基类调用它。
https://stackoverflow.com/questions/30399671
复制相似问题