Помогите днищу. Не могу придумать как сделать такую иерархию.
Есть набор операций, пусть будет add/sub/mul/div. Есть общий класс, который реализует представление и реализацию этих операций. И есть конкретные классы самих операций, которые реализуют и хранят уникальные данные/методы.
Как это реализовать.
namespace op {
class op_base {//т.е. это общий класс для операций
public:
op_base(int a, int b) : a(a), b(b) {}
int op();//т.е. это конкретная операция, которая как-то должна экспортироваться из каждой конкретной операции;
operator int() {return op();}
protected:
int a, b;
};
class op_add {//это конкретная операция.
int op() {return a + b};//конкретная операция
};
class op_mul {//это конкретная операция.
int op() {return a * b};//конкретная операция
};
//в конечном итоге нам надо получить объект op_base, в котором op() бы заменялась на конкретную реализацию.
//т.е. и
add(1, 2);
//и
mul(1, 2);
//были объектами op_base, но в чём-то были уникальны.
};
Я уже не могу - помогите. Эти перекрёстные ссылки меня доконают.
//попытка запилить на вариенте не удалась так же, как и сотни других.
namespace variant_hell {
struct op_add; struct op_mul;
using op_var = boost::variant<op_add *, op_mul *>;
class op_visitor : public boost::static_visitor<int> {
public:
int operator()(op_add * op) const {return op->op();}
int operator()(op_mul * op) const {return op->op();}
};
class operation {
public:
operation() {}
template<typename op> operation(int a, int b, boost::mpl::identity<op>) : a(a), b(b), cop { new op{*this}} {}
operator int() {
return boost::apply_visitor(op_visitor(), cop);
}
public:
int a, b;
private:
op_var cop;
};
struct op_add {
op_add(operation & base) : base(base) {}
int op() {return base.a + base.b;}
operation & base;
};
struct op_mul {
op_mul(operation & base) : base(base) {}
int op() {return base.a * base.b;}
operation & base;
};
template<typename T> struct wrapper {
wrapper(int a, int b) : op(a, b, boost::mpl::identity<T>()) {}
operator operation() {return op;}
operation op;
};
auto add(int a, int b) {return wrapper<op_add>(a, b);}
}
Операции должны быть именно полноценными, отдельными классами. Класс «операция» должен быть один на всех. Класс операция - основной, который должен иметь в себе доступ к сабклассам, которые «операции».
Отдельные операций тысячи. Поэтому никакая «шаблонная база» не подходит.
Вариант с вариантом хорошо ложится на логику, но я так и не смог.
Нагинерить тонны лапши не проблема.
Может я делаю что-то не так и это делается проще?