我知道boost.org上的教程解决了这个问题: Boost.org Signals Tutorial,但这些例子并不完整,有些过于简化.那里的例子没有显示包含文件,代码的某些部分有点模糊.
这就是我需要的:
ClassA引发多个事件/信号
ClassB订阅这些事件(多个类可以订阅)
在我的项目中,我有一个较低级别的消息处理程序类,它将事件引发到业务类,该业务类对这些消息进行一些处理并通知UI(wxFrames).我需要知道这些可能是如何连线的(什么顺序,谁叫谁等).
Boost.Signals允许使用槽的返回值的各种策略来形成信号的返回值.例如,添加它们,形成vector它们,或返回最后一个.
常见的智慧(在Qt文档中表达[编辑:以及该问题的一些答案])是Qt信号不可能有这样的事情.
但是,当我在以下类定义上运行moc时:
class Object : public QObject {
Q_OBJECT
public:
explicit Object( QObject * parent=0 )
: QObject( parent ) {}
public Q_SLOTS:
void voidSlot();
int intSlot();
Q_SIGNALS:
void voidSignal();
int intSignal();
};
Run Code Online (Sandbox Code Playgroud)
不仅没有moc抱怨具有非void返回类型的信号,它似乎以允许返回值传递的方式主动实现它:
// SIGNAL 1
int Object::intSignal()
{
int _t0;
void *_a[] = { const_cast<void*>(reinterpret_cast<const void*>(&_t0)) };
QMetaObject::activate(this, &staticMetaObject, 1, _a);
return _t0;
}
Run Code Online (Sandbox Code Playgroud)
所以:根据文档,这件事是不可能的.那么moc在这做什么?
插槽可以有返回值,那么我们可以将带有返回值的插槽连接到具有返回值的信号吗?毕竟,这可能吗?如果是这样,它有用吗?
编辑:我不是要求解决方法,所以请不要提供任何解决方法.
编辑:它显然在Qt::QueuedConnection模式中没用(QPrintPreviewWidget …
我的应用程序可能会受益于在本土解决方案中使用boost的信号库之一.
应用程序是多线程的,但执行信号处理的部分是单线程的.
如果多线程不是问题,有没有理由比Boost.Signal更喜欢Boost.Signals2?
我在本机C++类中使用boost :: signal,现在我在C++/CLI中编写.NET包装器,这样我就可以将本机C++回调公开为.NET事件.当我尝试使用boost :: bind来获取托管类的成员函数的地址时,我得到编译器错误3374,说我不能获取成员函数的地址,除非我创建一个委托实例.有谁知道如何使用boost :: bind绑定托管类的成员函数?
为了澄清,以下示例代码导致编译器错误3374:
#include <boost/bind.hpp>
public ref class Managed
{
public:
Managed()
{
boost::bind(&Managed::OnSomeEvent, this);
}
void OnSomeEvent(void)
{
}
};
Run Code Online (Sandbox Code Playgroud) 我目前在单线程应用程序中运行来自其他人库的函数Foo.大多数时候,我打电话给Foo并且它很快,有时候,我打电话给Foo并且它需要永远.我不是一个耐心的人,如果Foo要永远服用,我想停止执行Foo而不是用这些参数调用它.
以受控方式调用Foo的最佳方法是什么(我当前的环境是POSIX/C++),这样我可以在一定的秒数后停止执行.我觉得在这里做正确的事情就是创建第二个线程来调用Foo,而在我的主线程中我创建了一个计时器函数,如果它没有时间,它最终将发出第二个线程的信号.
还有另一个更贴切的模型(和解决方案)吗?如果没有,Boost的Signals2库和Threads会不会这样做?
我在多个地方读到Boost.Signals不是线程安全但我没有找到更多关于它的细节.这个简单的引用并没有说真的那么多.现在大多数应用程序都有线程 - 即使它们试图是单线程的,它们的一些库也可能使用线程(例如libsdl).
我想实现没有其他线程无法访问插槽的问题.所以在这个意义上它至少是线程安全的.
但到底有什么作用,哪些不行?只要我不同时访问它,它是否可以在多个线程中使用它?即如果我在插槽周围建立自己的互斥锁?
或者我被迫只在我创建它的那个线程中使用插槽?或者我第一次使用它的地方?
我想知道是否有更好的方法将一个类的Boost信号直接连接到另一个类的信号?
例如,想象一个具有一堆成员的外观类,它们提供自己的信号.现在假设立面想暴露这些信号.我通常最终编写样板方法,然后将其作为信号处理程序连接.
using namespace boost::signal;
class A
{
public:
A(){};
virtual ~A(){};
signal<void()> signalA;
};
class B
{
public:
B(){};
virtual ~B(){};
signal<void()> signalB;
};
class Facade
{
private:
A& a;
B& b;
public:
Facade(A& refA, B& refB)
: a(refA), b(refB)
{
// connect A's signal to facadeSignalA
a.signalA.connect(boost::bind(&Facade::forwardedSignalA, this));
// connect B's signal to facadeSignalB
b.signalB.connect(boost::bind(&Facade::forwardedSignalB, this));
}
virtual ~Facade() {};
// user visible signals
signal<void()> facadeSignalA;
signal<void()> facadeSignalB;
private:
// ugly boilerplate code used to forward …Run Code Online (Sandbox Code Playgroud) 我正在尝试完成boost :: signal教程,网址为http://www.boost.org/doc/libs/1_47_0/doc/html/signals/tutorial.html#id2850736
但是,Eclipse CDT使用我使用的任何语法显示解析错误
我有
#include <boost/signals.hpp>
Run Code Online (Sandbox Code Playgroud)
首选语法
boost::signal<void (float, float)> sig;
sig.connect(&print_sum);
Run Code Online (Sandbox Code Playgroud)
信号处的模板参数无效
方法'connect'无法解析
便携语法
boost::signal2<float, float, float> sig;
sig.connect(&print_sum);
Run Code Online (Sandbox Code Playgroud)
方法'connect'无法解析
符号'signal2'无法解析
我使用eclipse 3.7
任何人都可以告诉我boost::signals同步或异步调用的插槽吗?
例如,我有这段代码:
struct Hello
{
void operator()() const
{
std::cout << "Hello ";
}
};
struct World
{
void operator()() const
{
std::cout << " world!" << std::endl;
}
};
boost::signal<void ()> sig;
sig.connect(Hello());
sig.connect(World());
sig();
cout << "Foo";
Run Code Online (Sandbox Code Playgroud)
执行线程如何工作?执行是等待Hello()还是World()执行,之后"Foo"是打印还是异步调用它们(打印"Foo"并以未定义的顺序调用Hello()和World()执行)?
我正在尝试将boost :: signal的触发包装到boost :: bind对象中.所以我想要的是在调用boost :: function时用一些预先打包的参数调用信号.
我有的是这个:
boost::signals2::signal<void(int)> sig;
boost::function<void()> f = boost::bind(
&(sig.operator()), &sig, 10);
Run Code Online (Sandbox Code Playgroud)
但这不起作用.我收到以下错误:错误:没有匹配函数调用bind(,...
我也试过这个:
boost::function<void()> f = boost::bind(
(void(boost::signals2::signal<void(int)>::*)(int))
&(sig.operator()), &sig, 10);
Run Code Online (Sandbox Code Playgroud)
但后来我得到了"没有上下文类型信息的重载函数的地址".
那么什么是正确的语法?
boost-signals ×10
c++ ×8
boost ×5
boost-bind ×2
asynchronous ×1
boost-thread ×1
c++-cli ×1
delegates ×1
eclipse-cdt ×1
execution ×1
qt ×1
return-value ×1
watchdog ×1