Что касается проблем с тем, что QThreadPool::start()
не является виртуальной функцией, вы можете сделать что-то вроде этого:
Вместо переопределения функции вы можете использовать свой подкласс в MyTask и использовать другую функцию, которая вызовет run. Примерно так:
class MyThreadPool : public QThreadPool {
public:
void enqueue_and_run(QRunnable *runnable, int priority = 0) {
m_Queue.enqueue(runnable);
QThreadPool::start(runnable, priority);
}
const QQueue<QRunnable *>& queue() const {
return m_queue;
}
private:
QQueue<QRunnable *> m_queue;
};
class MyTask: public QRunnable {
public:
virtual void run() {
m_threadPool.enqueue_and_run(/*another task*/);
m_threadPool.enqueue_and_run(/*a third task*/);
}
private:
MyThreadPool &m_threadPool;
};
Затем запустите тот же тестовый код:
MyThreadPool threadPool;
threadPool.enqueue_and_run(new MyTask(threadPool));
threadPool.waitForDone();
QQueue<QRunnable *> Queue({ /*another task and a third task*/ });
Assert::IsEquavalent(threadPool.queue(), Queue);
Это не самый элегантный способ сделать это, но он проясняет ваши намерения.
В качестве альтернативы, если вы хотите сохранить общий интерфейс, вы можете использовать базовую функцию перегрузки:
template <class TPool>
void start(TPool* pool, QRunnable *runnable, int priority = 0) {
pool->start(runnable, priority);
}
void start(MyThreadPool* pool, QRunnable *runnable, int priority = 0) {
pool->enqueue_and_run(pool, runnable, priority);
}
Тогда ваш тестовый код будет работать почти так же, как и исходный:
MyThreadPool threadPool;
start(threadPool, new MyTask(threadPool));
threadPool.waitForDone();
// ... rest of the code