回调函数如何修改对象成员?

时间:2018-07-11 15:56:47

标签: c++ callback

为说明这个问题,让我们想象一个虚拟的示例,其中有一个来自外部API的函数:

// This function is run in a separated thread
void Transfert(string source, string destination, void (*callbackFunction)(int))
{
    for(int i = 0; i < 100; i++)
    {
        // Simulation of a file transfert
        // ...
        // 

        // We call the callback function to update the progression of the file transfert
        callbackFunction(i);
    }
}

我想使用此函数传输文件,并在回调函数的帮助下跟踪进度。这是我的代码:

// Class containing information about the transfert
class FileTransfert
{
public:
    FileTransfert(string, string);
    void MyCallback(int);

    // Those members are public to simplify this example but should be private
    long m_progress;
    string m_source;
    string m_destination;
};

FileTransfert::FileTransfert(string source, string destination)
{
    m_source = source;
    m_destination = destination;
}

// Used to update the progress variable
void FileTransfert::MyCallback(int progress)
{
    m_progress = progress;
}

int main(int argc, char* argv[])
{
    FileTransfert f("source.txt", "destination.txt");

    // It's a new thread
    Transfert(f.m_source, f.m_destination, f.MyCallback); // Compilation error

    // Now I want to follow the transfer with the m_progress variable

    return 0;
}

我的班级FileTransfert有一个m_progress成员,我想在文件传输期间刷新它。因此,我创建了一个用于更新m_progress的回调函数。 问题是我不能使用对象的方法作为回调函数。

所以,这是我的问题:如何修改代码以适应转移的进程?
我有一些限制:我必须从{{1} Transfert类之外的函数,而FileTransfert变量必须在m_progress类之内。换句话说,我无法更改代码的所有体系结构。

重要说明:我无法更改FileTransfert函数的代码和签名。在这两个问题(herehere)的答案中,我们更改了函数的签名,但我不能更改。


编辑

正如我在评论中所说,如果我不能更改Transfert函数的签名,就没有适当的解决方案。一种想法是使用全局变量,但在多线程环境中可能会非常危险。

0 个答案:

没有答案