виртуальный метод — Использование абстрактных классов в C ++ для функций более высокого порядка

Во-первых, я знаю, что ответ где-то там, но я искал все утро и не нашел его.

Мой вопрос касается того, как в 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();
}
};

Что с этим не так? Или как бы вы решили это?

-1

Решение

Если бы на самом деле была только одна функция-член, я бы реализовал это с помощью функторов и сделал бы 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_;
};
1

Другие решения

Мой вопрос был немного сомнительным. На самом деле я немного быстро опубликовал это. В любом случае, я надеюсь, что кто-то найдет это полезным.

Спасибо за ваши ответы. Я отполировал мой пример, и следующее фактически скомпилируется и запустится:

#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;
}
0

По вопросам рекламы [email protected]