c++ - 从回调中访问数据

标签 c++ callback global-variables

我有一些代码和数据,它们当前都封装在一个结构中,而该结构又位于一个命名空间内。我正在尝试集成一个外部库,它使用老式的回调。我需要在回调上下文中访问我的数据,但回调 API 不提供添加个性化参数的方法。

我知道规避这个问题的唯一方法是向我的结构添加一个全局指针,以便回调知道在哪里找到数据,或者使用一堆 boost 类从我的结构创建一个假函数指针要使用的回调。这两个选项感觉更像是绕过 OOP 限制,而不是实际的解决方案。

因此,我正在争论是否完全放弃该结构,并将其转换为独立的代码和数据。本质上,数据将成为全局的(或更可能的是,包装在全局结构中),但将在其 namespace 的范围内。

使数据“全局化”的理由:

  • 代码在程序中具有单一用途,并且在程序的生命周期中始终使用同一组数据。数据永远不会分配或释放。
  • 此代码和数据从未被实例化。从来没有、也永远不会有多个拷贝。
  • 我不喜欢 OOP(我使用 C++,因为它是完成这项工作的最佳工具),因此我认为没有必要仅在原则上对其进行封装。

但是,我想避免一个缺点:

  • 即使数据位于单独的命名空间中(并且忽略我是唯一编写此程序的人这一事实),也没有什么可以阻止程序的其他部分访问此数据。如果真的发生了,我将没有简单的方法来追踪它。

到目前为止,我唯一的想法是将全局数据包装在未命名的命名空间中。出于所有意图和目的,这应该使其对代码库的其余部分不可见,并消除不使用全局变量的最常见原因。然而,这也意味着访问它所需的代码必须全部包含在一个文件中,如果该文件变大,这可能会变得很痛苦。

是否还有其他我没有想到的选择,或者这已经是最好的选择了吗?

最佳答案

您可以只使用一些模板化静态函数来为您提供数据指针,尽管您必须在编译时指定这些:

#include <iostream>
using namespace std;

template <class Data, int ID>
struct ext_library_context
{
    static Data data;
    static void callback()
    {
        // callback code, using data
        cout << data << endl;
    }
};

template <class Data, int ID>
Data ext_library_context<Data, ID>::data;

void ext_library_call(void callback())
{
    callback();
}

int main()
{
    int d1 = 1;
    ext_library_context<int, 1>::data = d1;

    int d2 = 2;
    ext_library_context<int, 2>::data = d2;

    ext_library_call(ext_library_context<int, 1>::callback);
    ext_library_call(ext_library_context<int, 2>::callback);
}

只要您为每次调用使用唯一的数据/ID 模板参数组合,就不会有任何问题。

关于c++ - 从回调中访问数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7762506/

相关文章:

javascript - AJAX 中 HTTP 对象的更简洁语法?

javascript - 无法更新函数内部的全局变量并在其外部调用它(jQuery)

python - 销毁按钮的旧回调并安装新回调

javascript - 如何将回调函数包装在其他回调函数中并从那里调用?

javascript - 等于函数的变量是否被视为全局变量?

python - 如何避免在此递归函数中使用全局变量并改进我的代码?

c++ - 我可以删除在另一个进程中创建的 HBITMAP 对象吗?

c++ - 防止 visual studio 创建浏览信息 (.ncb) 文件

c++ - 运行固定数量的线程

c++ - 启用 Windows Aero 主题后如何在标题栏上绘制位图图标