Создание родительского класса с общим методом и наследование от
него — это как раз правильный объектно-ориентированный подход,
который решил бы проблему без "черной магии" и спецбиблиотек. В C++ есть несколько чистых способов решить эту задачу:
- 1. Базовый класс с виртуальным методом:
class Base {
public:
virtual void method() = 0; // Чисто виртуальный метод
virtual ~Base() = default; // Виртуальный деструктор для корректного удаления
};
class ClassA : public Base {
public:
void method() override { /* реализация для A */ }
};
class ClassB : public Base {
public:
void method() override { /* реализация для B */ }
};
- 2. Использование шаблонов и концепции полиморфизма времени компиляции:
template <typename T>
void callMethod(T& obj) {
obj.method(); // Требуется только наличие метода с подходящей сигнатурой
}
- 3. Использование std::function и лямбда-выражений для более гибкого подхода:
std::function<void()> createMethodPtr(SomeObject& obj) {
return [&obj]() { obj.method(); };
}
При использовании "указателя на метод объекта" для разных классов без общего предка возникают проблемы с разной структурой виртуальных таблиц и смещениями методов, что и требует "черной магии" для обхода стандартного поведения.
Подход с наследованием от общего базового класса — это более безопасный, переносимый и поддерживаемый способ, который следует идиомам C++ и не приводит к непредсказуемым побочным эффектам.