C ++ указатель на функцию и наследование - PullRequest
2 голосов
/ 17 июня 2010

У меня есть общий математический метод, который работает с набором функций (с большим количеством переменных и состояний, поэтому он не может быть статическим). Я реализовал метод в родительском классе, и я хочу объявить разные наборы функций в каждом дочернем классе.
Я пытаюсь сделать что-то вроде этого:

class A {
public:
    typedef int (A::*func)();
    func * fs;
    void f() { /*call functions from this->fs*/ }
};

class B : public A {
public:
    int smth;

    B(int smth) {
         this->smth = smth; //user-provided variables

        //there may be a lot of functions with same interface
        this->fs = new func[1];
        fs[0] = &B::f;
    }

    int f() {
        return smth + 1;
    }
};

Сбой с этой ошибкой: ошибка C2440: «=»: невозможно преобразовать из «int (__thiscall B :: *) (void)» в «A :: func»

Или «IntelliSense: указатель на связанную функцию может использоваться только для вызова функции», если я пытаюсь использовать & this-> f;

Ответы [ 2 ]

2 голосов
/ 17 июня 2010

Любопытно, что повторяющийся шаблон поможет.

template<typename Derived>
class A {
public:
    typedef int (Derived::*func)();
    func * fs;
    void f()
    {
        Derived* const This = static_cast<Derived*>(this);
        /* call functions like (This->*(fs[0]))() */
    }
};

class B : public A<B> {
public:
    int smth;

    B(int smth) {
         this->smth = smth; //user-provided variables

        //there may be a lot of functions with same interface
        this->fs = new func[1];
        fs[0] = &B::f;
    }

    int f() {
        return smth + 1;
    }
};
1 голос
/ 17 июня 2010

Возможно, будет работать массив boost::function:

#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
#include <vector>

struct A
{
    virtual ~A(void) {}; // base classes should always have virtual destructors

    typedef std::vector<boost::function<int(void)> > function_array;
    function_array mFunctions;
};

struct B : A
{
    B(int pX) : mX(pX) // use initializer lists
    {
        mFunctions.push_back(boost::lambda::bind(&B::foo, this));
    }

    int foo(void)
    {
        return mX + 1;
    }

    int mX;
};

int main(void)
{
    B b(5);
    A& a(b);

    int x = a.mFunctions[0]();
    // x is 6
}

Ваши цели до сих пор неясны.(Выше не было смысла для A быть базовым классом. Почему бы не иметь функцию типа get_functions, которая просто возвращает массив функций, которые все настроены и готовы к использованию, например?)1007 *


Какая у вас здесь более широкая картина?Похоже, вы ищете виртуальные функции:

struct A
{
    virtual ~A(void) {} // base classes should always have virtual destructors

    virtual int foo(void) const = 0;
};

struct B : A
{
    B(int pX) : mX(pX) {}

    int foo(void) const
    {
        return mX + 1;
    }

    int mX;
};

int main(void)
{
    B b(5);
    A* a = &b;

    int x = a->f(); // calls B::foo(), polymorphic behavior thanks to virtual
    // x is 6
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...