Is it possible to use signal inside a C++ class?

前端 未结 5 1595
独厮守ぢ
独厮守ぢ 2020-12-02 13:19

I am doing something like this:

#include 

class myClass {
public: 
    void myFunction () 
    {
        signal(SIGIO,myHandler);
    }

            


        
5条回答
  •  执笔经年
    2020-12-02 14:06

    The second parameter of signal should be a pointer to a function accepting an int and returning void. What you're passing to signal is a pointer to a member function accepting an int and returning void (its type being void (myClass::*)(int)). I can see three possibilities to overcome this issue:

    1 - Your method myHandler can be static: this is great, make it static

    class myClass 
    {
      public:
        void myFunction () 
        {
            signal(SIGIO, myClass::myHandler);
        }
    
        static void myHandler (int signum)
        {
            // handling code
        }
    };
    

    2 - Your method shouldn't be static: if you're planning to use signal with only one instance, you can create a private static object, and write a static method that simply call the method on this object. Something along the lines of

    class myClass 
    {
      public:
        void myFunction () 
        {
            signal(SIGIO, myClass::static_myHandler);
        }
    
        void myHandler (int signum)
        {
            // handling code
        }
    
        static void static_myHandler(int signum)
        {
            instance.myHandler(signum);
        }
    
      private:
        static myClass instance;
    };
    

    3 - However, if you're planning on using the signal with multiple instances, things will get more complicated. Perhaps a solution would be to store each instance you want to manipulate in a static vector, and invoking the method on each of these :

    class myClass
    {
      public:
        void myFunction () // registers a handler
        {
            instances.push_back(this);
        }
    
        void myHandler (int signum)
        {
            // handling code
        }
    
        static void callHandlers (int signum) // calls the handlers
        {
            std::for_each(instances.begin(), 
                          instances.end(), 
                          std::bind2nd(std::mem_fun(&myClass::myHandler), signum));
        }
      private:
        static std::vector instances;
    };
    

    and somewhere, do a single call to

    signal(SIGIO, myClass::callHandlers);
    

    But I think that if you end up using the last solution, you should probably think about changing your handling design :-)!

提交回复
热议问题