我原本以为我理解了继承、虚函数和函数重载,但是现在有一个问题,这些功能之间的相互作用似乎让我很困扰。
假设我有一个简单的基类,其中包含一个重载的虚函数,还有一个从它派生的第二个类:
class b {
public:
virtual int f() { return 1; }
virtual int f(int) { return 2; }
};
class d : public b {
public:
virtual int f(int) { return 3; }
};
请注意,派生类d
只覆盖了一个重载的虚函数。
我可以实例化一个d
类对象并在其上调用f(int)
,没有问题:
d x;
std::cout << x.f(0) << std::endl;
但是当我尝试调用这个无参函数时:
std::cout << x.f() << std::endl;
IT出现错误!gcc显示“没有找到匹配的函数调用'd::f()';候选项为: virtual int d::f(int)”。clang则表示“函数调用参数太少,期望1个,实际0个;你是否指的是 'b::f'?”尽管d
继承自b
,后者具有一个0参数的f()
方法,编译器仍忽略了这一点,并试图调用d
的1参数方法。
我可以通过在派生类中重复定义0参数函数来修复此问题:
class d : public b {
public:
virtual int f() { return 1; }
virtual int f(int) { return 3; }
};
或者,正如clang错误信息所建议的那样,我可以使用一种我从未想到过会起作用的笨拙消歧语法:
std::cout << x.b::f() << std::endl;
然而我的问题是,我违反了什么规则?这个规则试图强制执行/保护/捍卫什么?我认为我在这里尝试做的正是我认为继承应该用于的事情。