【问题标题】:Juggling with pointer-to-member-functions within class declaration在类声明中处理指向成员函数的指针
【发布时间】:2019-07-16 16:27:38
【问题描述】:

我试图让一个成员函数即时将自己重定向到其他成员函数。这是我想要实现的一些简化的伪代码:

class Foo
{
    public:
            Foo();

            int counter = 0;

            void slaveA() { counter++; };
            void slaveB() { counter--; };

            void (*master)() = &slaveA;

            void toggleSlave()
            {
                _useB = !_useB;

                if (_useB)
                    master = &slaveB;
                else
                    master = &slaveA;
            }

    private:
            boolean _useB = false;
}; 


Foo foo;

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    if (random(2) == 0)
        foo.toggleSlave();

    foo.master();
    Serial.println(foo.counter);
    delay(500);
}

但是,无论我做什么,我都会遇到这些错误:

cannot convert 'void (Foo::*)()' to 'void (*)()' in initialization
cannot convert 'void (Foo::*)()' to 'void (*)()' in assignment

在我的主项目中,master 的等效项将在硬件允许的情况下以至少 5 个从站的速度被调用,这就是为什么我试图在函数指针之间切换而不是在内部放置 if-else master.

我读过一堆说静态函数将是首选方法的东西,但我需要从属方法能够操纵成员变量,理想情况下,我希望所有内容都包含在类声明中,因此从技术上讲对象引用对所有涉及的成员函数都可用。

这样的事情可能吗?

【问题讨论】:

    标签: c++ class arduino function-pointers


    【解决方案1】:

    由于从属是非静态成员函数,master 需要是指向成员函数的指针,而不是指向函数的指针。代码如下所示:

    class Foo
    {
        public:
                Foo();
    
                int counter = 0;
    
                void slaveA() { counter++; };
                void slaveB() { counter--; };
    
                void (Foo::*master)() = &Foo::slaveA;
    
                void toggleSlave()
                {
                    _useB = !_useB;
    
                    if (_useB)
                        master = &Foo::slaveB;
                    else
                        master = &Foo::slaveA;
                }
    
        private:
                bool _useB = false;
    };
    
    void loop()
    {
        if (random(2) == 0)
            foo.toggleSlave();
    
        (foo.*foo.master)();
        Serial.println(foo.counter);
        delay(500);
    }
    

    [Live example]

    由于(foo.*foo.master)() 的语法相当难看,我建议将master 设为foo 中的函数,并将成员指针设为其实现细节:

    class Foo
    {
        public:
                Foo();
    
                int counter = 0;
    
                void slaveA() { counter++; };
                void slaveB() { counter--; };
    
                void master() {
                  (this->*_master)();
                }
    
                void toggleSlave()
                {
                    _useB = !_useB;
    
                    if (_useB)
                        _master = &Foo::slaveB;
                    else
                        _master = &Foo::slaveA;
                }
    
        private:
                void (Foo::*_master)() = &Foo::slaveA;
                bool _useB = false;
    };
    
    void loop()
    {
        if (random(2) == 0)
            foo.toggleSlave();
    
        foo.master();
        Serial.println(foo.counter);
        delay(500);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-27
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      相关资源
      最近更新 更多