Void函数指针用于修改另一个类中的数据

时间:2013-01-04 13:55:20

标签: c++ pointers function-pointers void-pointers

我将尽可能清楚地解释这一点。

我的例子目前涉及3个不同的类别。

  1. 我的模型类(让我们称之为MyModel.cpp
  2. 我的数据类MyModel的对象为(MyData.cpp
  3. 我的撤消重做类修改了我的模型(MyModelUR.cpp
  4. MyModelMyData个对象。 MyData包含一堆双打,每个双打都有自己的get和set函数。我的系统工作方式是通过调用redo()中的MyModelUR来调用setter。检测到更改时,redo()会调用此MyModel函数。但这超出了问题的范围。

    MyModelUR有3个函数,一个带有几个args的构造函数,undo()redo()不允许带任何args。

    会发生什么,我希望MyModelMyData中所需setter的函数指针传递给MyModelUR

    因此,这意味着MyModelUR的构造函数需要将函数指针作为arg,然后将其存储在私有全局变量中。到目前为止,我有类似的东西......

    MyModelUR::MyModelUR(MyModel* model, double newValue, void (*function)(double))
    {
        Model = model;
    
        NewValue = newValue;
    
        //FunctionToCall is a void*
        FunctionToCall = &function;
    }
    

    现在,在我的redo()函数中,我想使用FunctionToCall ...我正在尝试这样做,但它不起作用,只是让我编译错误......

    MyModelUR::redo()
    {
        Model->data()->FunctionToCall(NewValue);
    }
    

    我想以这种方式实现它,因此undo()中的每个double都不需要X个redo() / MyData函数。

    感谢您的帮助和建议,但在考虑回复时我有一些限制,因为我有一些其他限制,我想使用这种架构,而且我不能使用Boost库。

    TLDR;我想调用一个void函数指针,它在一个在一个对象上调用的单独的类中获取一个double。

    谢谢!

    编辑:在下面的评论之后,这就是我正在使用的......

    MyModelUR::MyModelUR(MyModel* model, double newValue, void (MyModel::*function)(double)) :
        Model(model),
        NewValue(newValue),
        FunctionToCall(function)
    {
    }
    
    void MyModelUR::redo()
    {
        MyData data = Model->data();
    
        data.*FunctionToCall(NewValue);
    }
    

    但是,这会在redo()中的第二行代码中引发错误:“必须使用'。'或' - > '来调用指向成员的指针功能在......“

1 个答案:

答案 0 :(得分:1)

首先,你的函数指针应该是方法指针,并且你正在尝试使用自由函数指针。

其次,不要尝试将其存储为void*,但不保证大小相同。只需将其声明为方法指针并停止转换。

最后,您当前正在(在void*中)存储瞬态函数指针参数地址,即使它是正确的类型。

你的代码应该是这样的:

class MyModelUR {
    ...
    MyModel *Model;
    double NewValue;
    void (MyData::*FunctionToCall)(double);
    ...
    MyModelUR(MyModel* model, double newValue, void (MyData::*function)(double))
      : Model(model), NewValue(newValue), FunctionToCall(function)
    {}
    void redo() {
        MyData &data = Model->data();
        (data.*FunctionToCall)(NewValue);
    }
};

实例化以下内容之一:

MyModelUR *ur = new MyModelUR(model, 3.4, &MyData::setSomeValue);

功能说明:如果你想要撤消,你需要一个getter方法指针以及存储旧值的地方。

美学注释:初始大写成员名称太可怕了,它与你用于类型的方案相同。只是IMO。