2010-06-16 3 views
2

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

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: '=': не удается преобразовать из 'междунар (__thiscall B :: *) (пустот)' в 'A :: func'

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

+0

Я не понимаю, что вы пытаетесь сделать. Пожалуйста, развернитесь дальше. –

+0

Какая у вас фотография? Кроме того, вместо ручного распределения используйте 'std :: vector'. – GManNickG

+1

Есть ли причина, по которой вы не можете реорганизовать приложение для использования виртуальных функций? Похоже, вы пытаетесь переопределить языковые возможности. –

ответ

2

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

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; 
    } 
}; 
+0

Спасибо, что работают именно так, как я хочу и могут быть реализованы с незначительными изменениями в коде :) – Andrew

+0

Как это отличается от того, что не просто использовать 'B' и помещать его в массив? (то есть, какая цель служит?) – GManNickG

+0

У меня может быть много математических моделей (B) и только один метод их решения (A). – Andrew

1

Может массив 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, что просто возвращает массив функций все настройки и готов к использованию, например?)


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

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 
} 
+0

Я не могу использовать виртуальные функции, потому что число их может различаться в каждом дочернем классе. – Andrew

+0

@pingvinus: Тогда вам нужно просветить нас о том, что такое большая картина. Покажите нам свои цели, а не тот метод, который, по вашему мнению, вам нужен. (Это то, за что мы нужны.) – GManNickG