将抽象基类中的所有纯虚函数定义为变量模板

问题描述 投票:0回答:2

是否可以声明一个可变参数函数来处理所有基类的纯虚函数?

class  Brain {

 private:
  virtual void SayGreeting(std::string greeting) = 0;
  virtual void SayGreetingLocation(std::string greeting, std::string location) = 0;
}

class Mouth: public Brain {

 public:
  template<typename T, typename... Args>
  void Say(T first, Args... args) {
    std::cout << args
    Say(args...)
  }
}

我希望Say覆盖SayGreetingSayGreetingLocation

c++ abstract-class variadic-templates pure-virtual
2个回答
3
投票

不是直接。成员函数模板不能是虚拟的,并且要覆盖基类中的方法,该方法需要具有相同的名称和签名。但是您可以这样做:

class  Brain {

 private:
  virtual void SayGreeting(std::string greeting) = 0;
  virtual void SayGreetingLocation(std::string greeting, std::string location) = 0;
};

class Mouth: public Brain {

  template<typename T, typename... Args>
  void Say(T first, Args... args) {
    std::cout << first;
    Say(args...)
  }
  public:
  void SayGreeting(std::string greeting) override {
      Say(greeting);
  }
  void SayGreetingLocation(std::string greeting, std::string location) override {
      Say(greeting,location);
  }
};

您的代码中有两个错误:缺少;std::cout << args应该为std::cout << first,而我没有解决的错误,您需要以某种方式终止递归。

PS:这也许只是一个例子,但是您的继承看起来很奇怪。 Mouth不是Brain,但公共继承的确为“是”关系建模。


2
投票

我不知道自动执行此操作的方法,我认为这是您要的。我不确定甚至没有可以将其半自动化的明智的宏技术。

当然,将参数手动转发到Say的实现很简单:

void Mouth::SayGreetingLocation(std::string greeting, std::string location)
{
    this->Say(greeting, location);
}

一些助手:

  • 您的Say()函数将需要一个0参数的“终止”重载。
  • const std::string&可能是更适合函数参数的类型,因为它通常更有效。 (除非您的函数更改了字符串。)
© www.soinside.com 2019 - 2024. All rights reserved.