C++函数指针和继承

3

我有一个通用的数学方法,它在一组函数下运作(具有许多变量和状态,因此无法静态执行)。我已经在父类中实现了该方法,并希望在每个子类中声明不同的函数集。
我尝试做如下操作:

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' 的参数

或者如果尝试使用 &this->f,则会出现 "IntelliSense:只能使用绑定函数的指针来调用函数" 的错误提示。


我不明白你想做什么,请进一步说明。 - Paul Nathan
你的大局是什么?此外,使用 std::vector 而不是手动分配。 - GManNickG
1
你是否有无法重构应用程序以使用虚函数的原因?看起来你正在尝试重新实现一种语言特性。 - Amardeep AC9MF
这听起来像是您想要通过虚函数提供的多态行为,但问题确实不太清楚 - 您到底想要实现什么? - Konrad Rudolph
我有一个通用的数学方法,它在一组函数下运行(具有许多变量和状态)。我已经在父类中实现了该方法,并希望在每个子类中声明不同的函数集。 - Andrew
2个回答

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

谢谢,这正是我想要的,并且可以通过对代码进行微小的更改来实现 :) - Andrew
这与仅使用B并将其函数放入数组有何不同?(即,A有什么作用?) - GManNickG
我可以有很多数学模型(B),但只有一种方法来解决它们(A)。 - Andrew
@pingvinus:但是并没有单独的A。 - GManNickG
@GMan:很可能缺少的是fs的计数。最好使用std::vector<func>。例如,考虑A可能会在B中定义的多个不同算法之间实现性能比较。A需要能够独立访问和计时每个算法,但它还需要访问整个集合,以便可以比较结果并确保它们在可接受的精度范围内一致。此外,输入存储在B的成员变量中,以便所有算法都可以访问它们。这只是一个很好使用的例子。 - Ben Voigt

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
}

我不能使用虚函数,因为每个子类中它们的数量可能会有所不同。 - Andrew
@pingvinus:那么你需要启发我们,告诉我们更大的目标是什么。展示你的目标,而不是你认为需要达成目标的方法。(这就是我们存在的意义。) - GManNickG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接