У меня есть класс с методом, который имеет много подписей (в приведенном ниже примере просто два для простоты).
class A
{
public:
virtual void f(int x) const
{
std::cout << "A::f(" << x << ")\n";
}
virtual void f(int x, int y) const
{
std::cout << "A::f(" << x << "," << y << ")\n";
}
};
и производный класс, который переопределяет методы родительского класса, добавляя некоторые логики c до и после вызова родительского метода.
class B : A
{
public:
void f(int x) const override
{
std::cout << "B::f(" << x << ")\n";
// do some stuff before the call
A::f(x);
// do some stuff after the call
}
void f(int x, int y) const override
{
std::cout << "B::f(" << x << "," << y << ")\n";
// do some stuff before the call
A::f(x, y);
// do some stuff after the call
}
};
Поскольку logi c до и после вызова родительского метода одинаков для всех переопределенных методов, я пытаюсь инкапсулировать все логи c в оболочке функции, которая принимает метод для вызова в качестве аргумента.
void wrapper(B const *b, std::function<void() const> &f)
{
std::cout << "wrapper(" << b << "," << &f << ")\n";
// do some stuff before the call
f();
// do some stuff after the call
}
class B : A
{
public:
void f(int x) const override
{
std::cout << "B::f(" << x << ")\n";
A const *p = this;
auto g = std::bind(static_cast<void (A::*)(int) const>(&A::f), p, x);
wrapper(this, g);
}
void f(int x, int y) const override
{
std::cout << "B::f(" << x << "," << y << ")\n";
A const *p = this;
auto g = std::bind(static_cast<void (A::*)(int, int) const>(&A::f), p, x, y);
wrapper(this, g);
}
};
Есть (как минимум) две проблемы с моим кодом,
-
std::bind
не генерирует желаемый std::function<void() const>
- , если вы вызываете объект
g
внутри метода f
класса B
, программа вводит бесконечный l oop, который я предположил это связано с полиморфизмом, то есть виртуальная таблица разрешается в B::f
вместо A::f
Есть ли у вас какие-либо предложения о том, как я могу исправить свой код, или вы знаете альтернативные способы достижения цель? * 1 025 *
Спасибо!