c++ - 基类中抽象方法的包装器实现

标签 c++ inheritance abstract-class

我有一个继承了许多子类的基类。我需要为一个抽象方法定义一个新的签名,它主要是一个包装器。这个我试过了

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)

我的问题是:

  1. 为什么不能解析D::f(string)
  2. 为什么以下任一方法可以解决问题?
    • 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/

相关文章:

c++ - 使用 boost::future 和 "then"延续

json - 在 Swift 中使类默认符合 Codable

c# - 具有内部类对象的抽象类构造函数继承

c++ - 如何为模板的内部类型专门化一个类?

c++ - 将对象的成员定义为值、指针或引用有什么区别

javascript - 在 JavaScript 中创建干净的、可继承的对象

python - "Partial Inheriting"来自 Django 模型

java - java抽象类中如何返回不同的数据类型

java - 摘要列表<人>

c++ - std::list resize 给出意想不到的结果