gpt4 book ai didi

c++ - 类通过回调提供数据

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:38:47 24 4
gpt4 key购买 nike

在使用回调更容易的 C 编程一段时间后,我最近又回到了 Visual C++。

我有一个控制 0..* 连接设备的单例类。我的想法是在此类中创建一个函数,它将迭代连接设备并通过回调将其发布到任何可能需要它的地方。

例如

Singleton class

typedef void (CALLBACK * PortListCallback_t)(ptrConstCComPortInfo_t);
.
.
.

void CCommsMgr::listPorts(PortListCallback_t cb)
{
PortInfoSetConstIter_t i;
for (i = m_setPorts.begin(); i != m_setPorts.end(); i++)
{
cb(*i);
}
}

首先,消费者是一个 MFC 对话框类,如果它的回调是静态的,它就可以正常工作。但是,为了访问对话框类的成员数据/函数,我需要将“this”传递给单例类并将其反射(reflect)回来。

例如

Singleton class

typedef void (CALLBACK * PortListCallback_t)(void *, ptrConstCComPortInfo_t);
.
.
.

void CCommsMgr::listPorts(void *pObj, PortListCallback_t cb)
{
PortInfoSetConstIter_t i;
for (i = m_setPorts.begin(); i != m_setPorts.end(); i++)
{
cb(pObj, *i);
}
}


Dialog Class

static void CALLBACK getPorts(void *obj, ptrConstCComPortInfo_t port);
.
.
.

void CALLBACK CMFC_iTFTPDlg::getPorts(void *obj, ptrConstCComPortInfo_t port)
{
CMFC_iTFTPDlg *pThis = (CMFC_iTFTPDlg*)obj;
// do something with it
}

我的问题 - 有更好的方法吗?静态函数感觉像是一个杂乱无章的东西,我不希望 Singleton 类受到它的使用方式的限制。如果我删除 getPorts 上的静态,它将无法编译。重复一遍,Singleton 类应该不知道它的消费者。

最佳答案

在 WhozCraig 的出色提示的帮助下,这就是我想出的:

#include <functional> // std::function, std::bind, std::placeholders
#include <iostream>
#include <vector>

class ConstCComPortInfo {};

using ptrConstCComPortInfo_t = ConstCComPortInfo*;
using callback_t = void(void*, ptrConstCComPortInfo_t);
using function_t = std::function<callback_t>;

// an example class with a member function to call
class foo {
public:
foo(const std::string& name) : instance_name(name) {}

void bar(void* something, ptrConstCComPortInfo_t c) {
std::cout << "foo::bar(" << instance_name << ") called\n"
"void* = " << something << "\n"
"ptrConstCComPortInfo_t = " << c << "\n";
}

private:
std::string instance_name;
};

// and a free function to call
void free_func(void* something, ptrConstCComPortInfo_t c) {
std::cout << "free_func_called\n"
"void* = " << something << "\n"
"ptrConstCComPortInfo_t = " << c << "\n";
}

int main() {
// some instances of the class
foo via_bind("called_via_bind");
foo via_lambda("called_via_lambda");

ptrConstCComPortInfo_t bork = nullptr; // dummy value

// a vector of callback subscribers
std::vector<function_t> subscribers{
&free_func,
std::bind(&foo::bar, &via_bind, std::placeholders::_1, std::placeholders::_2),
[&via_lambda](void* p, ptrConstCComPortInfo_t c) { via_lambda.bar(p, c); }
};

// perform callbacks
for(auto& cb : subscribers) {
cb(nullptr, bork);
}
}

输出:

free_func_called
void* = 0
ptrConstCComPortInfo_t = 0
foo::bar(called_via_bind) called
void* = 0
ptrConstCComPortInfo_t = 0
foo::bar(called_via_lambda) called
void* = 0
ptrConstCComPortInfo_t = 0

关于c++ - 类通过回调提供数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56183559/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com