Я хочу определить контейнер в базовом классе, который содержит функцию obj или что-нибудь, что может привести к моей цели. Эти функции obj могут вызывать функции производных классов. все они принимают одинаковые параметры.в базовом классе, как определить контейнер, содержащий функцию obj, которая может быть любой func производного класса?
#include <vector>
#include <functional>
#include <iostream>
class Foo {
Foo() {}
virtual ~Foo(){}
virtual void init()
{ registerCallback(0, &Foo::print_ori); }
void print_ori(int i) const { std::cout << i << '\n'; }
void registerCallback(int key, ??? cb) // NOT SURE HOW TO DEFINE THIS
{
callbacks[key] = cb;
}
void runCallbacks(int key, int n)
{
auto i = callbacks.find(key);
if (i != callbacks.end()) {
(*i)(*this, n);
}
}
std::map<int, std::function<void(const Foo&, int) > > callbacks; // obviously, it's wrong. how to fix it?
};
struct Foo2 : public Foo {
Foo2(int num) : Foo(num) {}
virtual void init()
{
Foo::init();
registerCallback(11, &Foo2::print1);
registerCallback(12, &Foo2::print2);
}
void print1(int i) const { std::cout << " - Foo2.p1 - " << i << endl; }
void print2(int i) const { std::cout << " - Foo2.p2 - " << i << endl; }
};
int main()
{
Foo* obj = new Foo2();
obj->init();
obj->runCallbacks(12, 456);
}
Это не будет правильно работать в любом случае, так как вы делаете 'UB', когда вы передаете' fobj' типа '' Foo' к print_ttt', и, таким образом, используя '' vtable' из Foo' в вызовите функцию, которая находится только в 'Foo2'. –
Есть ли какая-то особая причина, по которой вы не можете просто сохранить кучу ссылок Foo (и производных) и вызвать одну и ту же виртуальную функцию для каждого объекта? Возможно, ваш пример слишком прост для того, что вы действительно хотите сделать, но похоже, что вы должны это сделать. –
Вы правы. Но как я могу заставить его работать? Я хочу, чтобы базовый класс запускал набор функций зарегистрированного производного класса, которые принимают одинаковые параметры. – doufunao