【问题标题】:C++ have as parameters the subclasses of a given classC++ 将给定类的子类作为参数
【发布时间】:2020-07-21 17:17:24
【问题描述】:

我正在创建一个线程池,并且我有一些方法必须作为输入对象,这些对象是 Task 的子类。

我有这门课:

struct Task {
  virtual ~Task() = default;
  virtual void run();
};

线程池有这样的方法:

void submit(Task val);

我想通过子类化 Task 类并将这些对象传递给线程池来完成线程池必须执行的作业,例如:

class Example : public Task {
    ....
    void run() override {
         cout << this->sayHi << endl;
         ....
    }
}

class Example2 : public Task {
    ....
    void run() override {
         cout << this->a + this-> b << endl;
    }

Example e (3);
Example2 e2 ("Hello");

tp.submit(e);
tp.submit(e2);

我的问题是,如果我尝试通过编写 void run() = 0 使 Task 成为纯虚拟类,它会报错,因为虚拟类不能用作线程池的 submit 方法的参数。强>

是否有类似 Java 的功能,我可以在其中创建一个模板参数,指定该类型必须是给定类型的子类? (例如class C &lt; T extends Task&gt;)?

一种解决方案可能是实现 Task 的 run 方法并使其抛出异常,但如果 Task 被分心的人使用,这可能会在运行时导致问题,我更喜欢编译器检查的方式.

【问题讨论】:

  • void submit(Task val); ==> void submit(std::shared_ptr&lt;Task&gt; val);
  • @n.'pronouns'm。你可以解释吗?我是 C++ 新手
  • 我认为这个问题尊重所有 SO 准则。我解释了这个问题,我说了我试过的。而且您在关闭我时链接的问题没有回答我的问题。
  • @ninazzo 我建议您阅读 C++ 上下文中的动态调度和多态性。您的问题可能已结束,因为void submit(Task val); 的签名暗示误解了一个非常基本的概念 w.r.t。 C++ 中的多态性和虚方法分派 - 即您需要使用基类引用或指针才能多态地分派派生对象的成员函数。使用当前签名,submit 函数将导致派生对象(复制)slicing
  • ... 另外,作为另一个建议,任何与“我可以在 Java 中做到这一点,我将如何......他们的设计和常见模式的变化。考虑在学习 C++ 时保持清醒的头脑,不考虑任何常见的 Java 模式实现细节。

标签: c++ templates c++17 subclass virtual-functions


【解决方案1】:

纯虚类无法实例化,因为您没有纯虚函数的定义。

为了利用多态性,您的submit 函数应将指向Task 的指针作为参数,而不是实例化Task

void submit(std::shared_ptr<Task> val);

我建议你先阅读更多关于多态性的内容。

【讨论】:

    【解决方案2】:

    您可能需要考虑将 Task 用作函子,对于 lambda 来说最简单。

    .submit( [&i](){ ++i;});
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      相关资源
      最近更新 更多