我有一个继承了许多子类的基类。我需要为一个抽象方法定义一个新的签名,它主要是一个包装器。这个我试过了
class B {
public:
virtual void f() = 0;
void f(string msg) { /* print msg and call f() */ }
};
class D : public B {
public:
void f() override { /* implementatation */}
};
int main() {
D d;
d.f("msg");
}
但它没有编译并给出以下错误
error: no matching function for call to 'D::f(string)
我的问题是:
- 为什么不能解析
D::f(string)
? - 为什么以下任一方法可以解决问题?
- 将
f(string)
重命名为f2(string)
(丑陋) - 定义
D::f(string x) { B::f(x)}
(很难看,因为它必须在每个子类中定义) - 移除抽象方法,
B::f()
( Not Acceptable )
- 将
有更好的解决方案吗?
最佳答案
问题是您在此处隐藏 B::f(std::string)
:
class D : public B {
public:
void f() override;
};
当您调用 D.f("msg")
时,名称查找将在 D
中找到一个 f()
并停止查找。我们首先找到候选函数,然后执行重载解析。因为那个碰巧没有参数,你会得到编译错误。
如果你想使用f
的另一个重载,你需要把它也带入D
,像这样:
class D : public B {
public:
using B::f;
void f() override;
};
现在我们有了 D::f()
(被覆盖的虚函数)和 D::f(std::string )
(我们从 B
)。
另一种简单的解决方案是简单地重命名一个或另一个函数,这样一开始就不会遇到这个问题。
关于c++ - 基类中抽象方法的包装器实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31467692/