【发布时间】: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 < T extends Task>)?
一种解决方案可能是实现 Task 的 run 方法并使其抛出异常,但如果 Task 被分心的人使用,这可能会在运行时导致问题,我更喜欢编译器检查的方式.
【问题讨论】:
-
void submit(Task val);==>void submit(std::shared_ptr<Task> 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