我有一个继承了许多子类的基类。我需要为抽象方法定义一个新签名,它主要是一个包装器。我试过这个
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()
(不可接受)有更好的解决方案吗?
答案 0 :(得分:5)
问题是你隐藏 B::f(std::string)
:
class D : public B {
public:
void f() override;
};
当您致电D.f("msg")
时,名称查询会在f()
中找到一个D
并停止查找。我们首先找到候选函数然后执行重载决策。由于那个碰巧没有参数,你得到编译错误。
如果您想使用f
的其他重叠,您还需要将其带入D
,如下所示:
class D : public B {
public:
using B::f;
void f() override;
};
现在我们有D::f()
(重写的虚函数)和D::f(std::string )
(我们从B
引入)。
另一个简单的解决方案是简单地重命名一个或另一个函数,这样你就不会有这个问题。
答案 1 :(得分:1)
您使用的是NVI个身份证吗?如:
class B {
public:
virtual void f() = 0;
void f(string msg) {
/* print msg and call f() */
std::cout << msg;
f();
}
virtual ~B() {}
};
然后你应该尽可能尝试从基类(通过引用或指针)调用非虚拟成员函数,例如:
D d;
B& b = d;
b.f("msg");