Во-первых, я знаю, что ответ где-то там, но я искал все утро и не нашел его.
Мой вопрос касается того, как в Java выглядит
abstract class AbstractWorker {
public abstract int doIt();
}
class Thinker extends AbstractWorker {
public int doIt() { return 42; }
}
class Milkmaid extends AbstractWorker {
public int doIt() { return 1 + 2; }
}
class Worker {
public int getWorkDone(AbstractWorker worker) {
return worker.doIt();
}
}
Я думаю, что это должно быть возможно и в C ++. Но как мне это реализовать? Мой подход будет выглядеть так
struct AbstractWorker {
virtual int doIt() = 0;
};
struct Thinker : public AbstractWorker {
int doIt() { return 42; }
};
struct Milkmaid : public AbstractWorker {
int doIt() { return 1 + 2; }
};
struct Worker {
int getWorkDone(AbstractWorker &worker) {
return worker.doIt();
}
};
Что с этим не так? Или как бы вы решили это?
Если бы на самом деле была только одна функция-член, я бы реализовал это с помощью функторов и сделал бы getWorkDone
шаблон.
struct Worker {
template<typename F>
auto getWorkDone(F f) -> decltype(f())
{ return f(); }
};
В случае, если вам действительно нужно стирание типа над различными функторами, есть std::function
,
struct worker1 { int operator()() { return 23; } };
struct worker2 { int operator()() { return 5; } };
std::function<int()> func;
if(/* runtime stuff */ ) func = worker1();
else func = worker2();
Worker w;
w.getWorkDone(std::ref(func));
Функторы также могут быть использованы для поддержания состояния:
template<typename Func>
struct Worker {
Worker(Func f = Func()) : f_(f) {}
auto getWorkDone() -> decltype(f_())
{
// do something with the state in f_
return f_();
}
private:
Func f_;
};
Мой вопрос был немного сомнительным. На самом деле я немного быстро опубликовал это. В любом случае, я надеюсь, что кто-то найдет это полезным.
Спасибо за ваши ответы. Я отполировал мой пример, и следующее фактически скомпилируется и запустится:
#include <iostream>
struct AbstractWorker {
virtual ~AbstractWorker() {};
virtual int doIt() = 0;
};
struct Thinker : public AbstractWorker {
int doIt() { return 42; }
};
struct Milkmaid : public AbstractWorker {
int doIt() { return 1 + 2; }
};
struct Worker {
int getWorkDone(AbstractWorker &worker) {
return worker.doIt();
}
};
int main() {
Thinker work1;
Milkmaid work2;
Worker worker;
std::cout << "result of work1: " << worker.getWorkDone(work1) << std::endl;
std::cout << "result of work2: " << worker.getWorkDone(work2) << std::endl;
return 0;
}