boost::signal和std::bind混淆,我应该试试别的吗? 我试图找出一种方法,我可以把消息发送给C++中的其他对象。例如,当一个对象与另一个对象发生碰撞时,它将发送一条消息,说明发生了碰撞。我试图使用boost:signal,但它们似乎并不是我想要的,除非我只是以错误的方式使用它们

boost::signal和std::bind混淆,我应该试试别的吗? 我试图找出一种方法,我可以把消息发送给C++中的其他对象。例如,当一个对象与另一个对象发生碰撞时,它将发送一条消息,说明发生了碰撞。我试图使用boost:signal,但它们似乎并不是我想要的,除非我只是以错误的方式使用它们,c++,boost,C++,Boost,主要原因如下: 我真的不明白为什么即使知道我在堆栈上分配的对象已被销毁,这段代码仍然有效 class SomeClass { public: void doSomething() { std::cout << "Testing\n"; } }; int main(int argc, char** argv) { boost::signal<void ()> sig; { SomeClass

主要原因如下:

我真的不明白为什么即使知道我在堆栈上分配的对象已被销毁,这段代码仍然有效

class SomeClass
{
public:

   void doSomething()
   {
      std::cout << "Testing\n";
   }
};


int main(int argc, char** argv)
{
     boost::signal<void ()> sig;


     {
           SomeClass obj;
           sig.connect(std::bind(&SomeClass::doSomething, &obj));
     }

     sig();
}
为什么它仍然有效?我是否应该得到某种运行时错误,或者根本不调用该方法?我真的不希望这种情况真的发生,我希望一旦对象被破坏,连接就会丢失

我在考虑以另一种方式发送消息,可能是使用委托类型的Objective-C风格,在这种方式中,您将从类继承一条消息发送给您。但是,这又一次让我感到困惑,比如如果我想要多个委托,我会有一个委托指针数组,如果一个委托被破坏,我就必须将它从数组中删除。。。这可能会引起一些混乱

e、 g


有人能建议我如何实现我想做的事情吗?我真的很困惑我应该怎么做…

至少回答你的一些问题:

为什么它仍然有效?我是否应该得到某种运行时错误,或者根本不调用该方法

我想你只是幸运而已。对象被销毁,但仍然可以对其调用方法。这是未定义的行为,但在您的情况下,它不会崩溃

你不太清楚你想解决什么问题。因此很难判断什么是最佳解决方案。
对于您的学员方法,请查看
std::shared_ptr
std::weak_ptr
。您可以持有std::weak_ptr的数组,并通过这些数组调用您的代表


或者,
boost::signal
是正确的选择。请查看。

至少回答您的一些问题:

为什么它仍然有效?我是否应该得到某种运行时错误,或者根本不调用该方法

我想你只是幸运而已。对象被销毁,但仍然可以对其调用方法。这是未定义的行为,但在您的情况下,它不会崩溃

你不太清楚你想解决什么问题。因此很难判断什么是最佳解决方案。
对于您的学员方法,请查看
std::shared_ptr
std::weak_ptr
。您可以持有std::weak_ptr的数组,并通过这些数组调用您的代表

或者,
boost::signal
是正确的选择。看一看

为什么它仍然有效

它实际上是未定义的行为,因为正在对已破坏的对象调用
doSomething()
。(要查看这一点,请向析构函数添加一条print语句。)运行程序时,屏幕上打印了“Testing”,但程序可能已崩溃

你可以考虑将一个成员添加到<代码> SomeClass < /代码>。这样,在

SomeClass
析构函数中,可以断开信号插槽连接

为什么它仍然有效

它实际上是未定义的行为,因为正在对已破坏的对象调用
doSomething()
。(要查看这一点,请向析构函数添加一条print语句。)运行程序时,屏幕上打印了“Testing”,但程序可能已崩溃


你可以考虑将一个成员添加到<代码> SomeClass < /代码>。这样,在

SomeClass
析构函数中,可以断开信号插槽连接。

示例中的信号插槽是一个非虚拟成员函数,它不访问任何对象成员。非虚函数地址在编译时解析,这里不需要这个指针,所以没有崩溃的原因


另一方面,您可以使用信号“跟踪”功能自动断开插槽。请参见以下内容:中的跟踪;跟踪。示例中的信号槽是一个非虚拟成员函数,它不访问任何对象成员。非虚函数地址在编译时解析,这里不需要这个指针,所以没有崩溃的原因


另一方面,您可以使用信号“跟踪”功能自动断开插槽。请参见以下内容:中的跟踪;跟踪。

谢谢,boost::signals2::trackable是我一直在寻找的。然而,让我的库需要使用boost似乎很难看/不好做?。。。据我的程序员朋友说。主要原因是图书馆的规模。但是,因为我真的需要使用boost,所以我将使用它。除非这是个坏主意?@miguel.martin请注意,如果您使用信号2,您不必实现
可跟踪
,相反,您可以传递
弱ptr
。至于考虑使用或不使用Boost一般由于一些额外的KB -井,我不知道你的具体要求和编码指南,但一般来说,这种推理可以导致我们不使用STL和C++标准库,甚至可能不使用CRT的所有开销…谢谢,boost::signals2::trackable是我一直在寻找的。然而,让我的库需要使用boost似乎很难看/不好做?。。。据我的程序员朋友说。主要原因是图书馆的规模。但是,因为我真的需要使用boost,所以我将使用它。除非这是个坏主意?@miguel.martin请注意,如果您使用信号2,您不必实现
可跟踪
,相反,您可以传递
弱ptr
。至于考虑使用或不使用Boost,通常是由于一些额外的Kb,我不知道您的具体要求和编码准则,但一般来说,这种类型的
Testing
class ColliderDelegate
{
public:

    virtual ~ColliderDelegate() {}

    virtual void onCollisionEnter(Collider* sender, Collider* withWho) = 0;
    virtual void onCollisionExit(Collider* sender, Collider* withWho) = 0;
    virtual void onCollisionStay(Collider* sender, Collider* withWho) = 0;

private:

    // I would have to have an array of Collider's that this object is connected to,
    // so it can detatch itself when it's destroyed...
 };

 class Collider
 {
 public:
    void add(ColliderDelegate* delegate);
    void remove(ColliderDelegate* delegate);


    void checkForCollisionWith(Collider*);

 private:

     // I would have to have an array of ColliderDelegate's that this object
     // needs to send information to.
 };