Ste*_*mit 9 c++ inheritance virtual-functions overloading
我以为我理解了继承,虚函数和函数重载,但我有一个案例,其中有关于这些特性之间的相互作用的事情让我望而却步.
假设我有一个包含重载虚函数的简单基类,以及从中派生的第二个类:
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; }
};
Run Code Online (Sandbox Code Playgroud)
请注意,派生类d仅覆盖其中一个重载的虚函数.
我可以实例化一个类的对象d并f(int)在其上调用,没问题:
d x;
std::cout << x.f(0) << std::endl;
Run Code Online (Sandbox Code Playgroud)
但是当我尝试调用0参数函数时:
std::cout << x.f() << std::endl;
Run Code Online (Sandbox Code Playgroud)
它失败!gcc说"没有匹配函数来调用'd :: f()';候选者是:virtual int d :: f(int)".clang说"函数调用的参数太少,预期为1,有0;你的意思是'b :: f'吗?" 即使d派生出来的b是0-argument f()方法,编译器也会忽略它,并试图调用d1-argument方法.
我可以通过重复派生类中的0参数函数的定义来解决这个问题:
class d : public b {
public:
virtual int f() { return 1; }
virtual int f(int) { return 3; }
};
Run Code Online (Sandbox Code Playgroud)
或者,正如clang的错误消息所示,我可以使用一种愚蠢的消歧语法,我从来没有猜到它会起作用:
std::cout << x.b::f() << std::endl;
Run Code Online (Sandbox Code Playgroud)
但我的问题是,我打破了什么规则,试图强制执行/保护/捍卫的规则是什么?我以为我试图在这里做的就是我认为继承的那种东西.
这称为名称隐藏.
在派生类中声明具有相同名称的函数时,将隐藏基础中具有相同名称的所有函数.
为了获得对它们的非限定访问权限,using请在派生类中添加一个声明:
class d : public b {
public:
using b::f;
virtual int f(int) { return 3; }
};
Run Code Online (Sandbox Code Playgroud)