使用“std::function”从另一个对象调用对象的成员
Invoking member of an object from another one by using `std::function`
我试图在对象之间创建一个通信系统,其中控制器对象保留其他对象的成员函数向量,并在需要时调用它们
我读了几篇关于std::function
用法的文章,但找不到一篇涵盖这个用例的文章。
我的代码是:
#include <functional>
#include <Windows.h>
class Callable
{
};
class ClassA : public Callable
{
public:
double CallThis(double x, int y) const
{
MessageBoxW(NULL, L"CallThis() is called.", L"In ClassA", MB_ICONINFORMATION);
return x + y;
}
};
class ClassB : public Callable
{
public:
double CallMe(double x, int y) const
{
MessageBoxW(NULL, L"CallMe() is called.", L"In ClassB", MB_ICONINFORMATION);
return x + y;
}
};
class Caller
{
public:
void AddSubscriber( const Callable & ObjectToCall,
const std::function<double(const Callable &, double, int)> & Subscriber)
{
Subscribers.push_back(Subscriber);
ObjectsToBeCalled.push_back(ObjectToCall);
}
void CallSubscribers()
{
for (size_t i=0; i<Subscribers.size(); i++)
{
Subscribers[i](ObjectsToBeCalled[i], 1.0, 2);
}
}
private:
std::vector<std::function<double(const Callable &, double, int)>> Subscribers;
std::vector<const Callable &> ObjectsToBeCalled;
};
int APIENTRY wWinMain( _In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
// ...
ClassA ObjectA;
ClassB ObjectB;
Caller ObjectCaller;
ObjectCaller.AddSubscriber(ObjectA, &ClassA::CallThis);
ObjectCaller.AddSubscriber(ObjectA, &ClassB::CallMe);
Sleep(5000);
ObjectCaller.CallSubscribers();
// ...
}
奇怪的是,当我运行这段代码时,我自己的代码中没有任何编译器错误,但我从STL文件xmemory0
和vector
中得到了错误。错误为:
Error 1 xmemory0 527 error C2528: 'pointer' : pointer to reference is illegal
Error 2 xmemory0 528 error C2528: 'const_pointer' : pointer to reference is illegal
Error 3 xmemory0 561 error C2535: 'const Callable &(*std::allocator<_Ty>::address(const Callable &) throw() const)' : member function already defined or declared
Error 4 xmemory0 599 error C2528: '_Ptr' : pointer to reference is illegal
Error 5 xmemory0 604 error C2528: '_Ptr' : pointer to reference is illegal
Error 6 xmemory0 700 error C2528: 'pointer' : pointer to reference is illegal
Error 7 xmemory0 701 error C2528: 'const_pointer' : pointer to reference is illegal
Error 8 xmemory0 824 error C2535: 'const Callable &(*std::_Wrap_alloc<_Alloc>::address(const Callable &) const)' : member function already defined or declared
Error 9 xmemory0 890 error C2528: '_Ptr' : pointer to reference is illegal
Error 10 xmemory0 105 error C2528: 'abstract declarator' : pointer to reference is illegal
Error 11 xmemory0 107 error C2528: 'abstract declarator' : pointer to reference is illegal
Error 12 xmemory0 122 error C2528: 'pointer' : pointer to reference is illegal
Error 13 xmemory0 123 error C2528: 'const_pointer' : pointer to reference is illegal
Error 14 vector 773 error C2528: '_Pval' : pointer to reference is illegal
Error 15 vector 1184 error C2535: 'void std::vector<_Ty>::push_back(const Callable &)' : member function already defined or declared
Error 16 vector 1245 error C2535: 'std::_Vector_iterator<_Myvec> std::vector<_Ty>::insert(std::_Vector_const_iterator<_Myvec>,_Ty)' : member function already defined or declared
Error 17 vector 1494 error C2528: '_Ptr' : pointer to reference is illegal
Error 18 vector 1658 error C2528: '_Pval' : pointer to reference is illegal
我做错了什么?如何运行此代码?
(我的IDE是Microsoft Visual Studio 2012。)
查看您的代码,您最好存储std::function<double(double, int)>
,然后使用std::bind
将对象绑定到成员函数。
template <typename F>
void AddSubscriber( const Callable & obj,
F subscriber)
{
Subscribers.push_back(std::bind(subscriber, obj, _1, _2));
}
或者通过直接传递可转换为std::function<double(double, int)>
的东西,将Callable
与Caller
完全解耦:
class Caller
{
public:
template <typename F>
void AddSubscriber(F&& subscriber)
{
subscribers.emplace_back(std::forward<F>(subscriber));
}
void CallSubscribers()
{
for (const auto& subscriber : subscribers)
{
subscriber(1.0, 2);
}
}
private:
std::vector<std::function<double(double, int)> subscribers;
};
然后从调用方进行绑定。
Caller c;
ClassA a;
using namespace std::placeholders;
c.AddSubscriber(std::bind(&ClassA::CallThis, a, _1, _2));
在阅读了juancopanza的答案后,我重写了下面所附的代码。现在它按预期工作。
class ClassA
{
public:
double CallThis(double x, int y) const
{
MessageBoxW(NULL, L"CallThis() is called.", L"In ClassA", MB_ICONINFORMATION);
return x + y;
}
};
class ClassB
{
public:
double CallMe(double x, int y) const
{
MessageBoxW(NULL, L"CallMe() is called.", L"In ClassB", MB_ICONINFORMATION);
return x + y;
}
};
class Caller
{
public:
void AddSubscriber(std::function<double(double, int)> Subscriber)
{
Subscribers.push_back(Subscriber);
}
void CallSubscribers()
{
for (const auto & Subscriber : Subscribers)
{
Subscriber(1.0, 2);
}
}
private:
std::vector<std::function<double(double, int)>> Subscribers;
};
int APIENTRY wWinMain( _In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
// ...
ClassA ObjectA;
ClassB ObjectB;
Caller ObjectCaller;
ObjectCaller.AddSubscriber(std::bind(&ClassA::CallThis, ObjectA, std::placeholders::_1, std::placeholders::_2));
ObjectCaller.AddSubscriber(std::bind(&ClassB::CallMe, ObjectB, std::placeholders::_1, std::placeholders::_2));
Sleep(5000);
ObjectCaller.CallSubscribers();
// ...
}
相关文章:
- 检查哪个对象调用了另一个对象的对象方法
- 为什么数组中对象的析构函数在被另一个对象替换时不被调用?
- 如何创建一个对象创建函数,该函数将由与其关联的名称调用?
- 编译问题 C++ 同时,尝试通过调用另一个对象中的成员函数来创建 std:: 线程
- 我可以制作一个对象方法,如果单独调用,它将自行修改,但如果在复制初始化期间调用,则会返回一个新对象?
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 调用对象类方法,该方法在另一个对象类中的向量中
- 为什么在 C++ 中,当对象包含在另一个对象中时,复制构造函数被调用两次
- 我如何有boost.python调用一个函数来处理对象
- 指向struct的指针,包含指向对象的指针,我想调用一个函数
- 使用SWIG包装C 类,该类调用另一个对象成员函数
- 从另一个对象调用成员函数时出现问题
- 将一个对象的函数设置为由arduino库中的另一个对象调用
- 尝试将调用对象与另一个对象进行比较时出现分段错误
- 当一个没有参数的成员函数被c++中的一个对象调用时会发生什么
- 为什么在 const 对象上调用 std::move 在传递给另一个对象时会调用复制构造函数
- 从另一个 std::thread 调用 Qt 对象方法
- 将一个对象发送到另一个对象并调用first-objects方法
- 从另一个对象调用一个对象的函数时未定义的引用
- 你能从DLL中动态调用一个对象吗