ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
21 апреля
1510375 Топик полностью
Бoмж (06.04.2025 16:48, просмотров: 152) ответил AlexG на Там было не так просто. Использовался указатель на метод объекта, причем объекты были разных классов. C++ такое штатно не умеет (по крайней мере, не таким способом и не в той версии) и работало это путем черной магии и спецбиблиотеки. Как выяснилось, с побочными эффектами.
Создание родительского класса с общим методом и наследование от него — это как раз правильный объектно-ориентированный подход, который решил бы проблему без "черной магии" и спецбиблиотек. 

В C++ есть несколько чистых способов решить эту задачу:

  1. 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 */ }
};
  1. 2. Использование шаблонов и концепции полиморфизма времени компиляции:
template <typename T>
void callMethod(T& obj) {
    obj.method(); // Требуется только наличие метода с подходящей сигнатурой
}
  1. 3. Использование std::function и лямбда-выражений для более гибкого подхода:
std::function<void()> createMethodPtr(SomeObject& obj) {
    return [&obj]() { obj.method(); };
}

При использовании "указателя на метод объекта" для разных классов без общего предка возникают проблемы с разной структурой виртуальных таблиц и смещениями методов, что и требует "черной магии" для обхода стандартного поведения.

Подход с наследованием от общего базового класса — это более безопасный, переносимый и поддерживаемый способ, который следует идиомам C++ и не приводит к непредсказуемым побочным эффектам.

memento mori