2015-02-10 32 views
0

对于不知道如何描述我的问题,我表示歉意。我希望这个例子很清楚。如果您不知道传递方法的确切类别,如何将方法传递给类

//My Arduino based device has a real time clock for which I use a library 
#include <RTClib.h> 
RTC_DS3234 RTClock(PIN_CLOCK_CS); // uses SPI 
DateTime dt = RTClock.now(); 
// I also have written a logging class which is a singleton 
#include <Logger_SD.h> 
Logger_SD::Instance()->initializeSD(PIN_SD_CS,PIN_CLOCK_CS,&dt); 

所以我的记录器类现在在生成日志消息时使用指向dt的指针。不幸的是,每次我打电话给记录器时,我都必须更新dt,以便它有正确的日期和时间。

dt = RTClock.now(); 
Logger_SD::Instance()->msgL(INFO,F("Setting Up MPU6050 Gyro.")); 

我想通过RTClock.now()方法,它总是返回一个DateTime到Logger_SD所以它可以得到它自己该死的时间。不幸的是,有许多种RTC。我可以这样做:

RTC_DS1307 RTClock(0x68); // Uses i2c 
// or 
RTC_DS3231 RTClock(0x68); // Also I2c, but does more. 
// Lots more. 
// then again... 
DateTime dt; 
dt = RTClock.now(); 
// I'd like to do something like: 
DateTime myNow() return RTClock.now(); 
Logger_SD::Instance()->initializeSD(PIN_SD_CS,PIN_CLOCK_CS,&myNow); 

这些都返回datetime一个NOW()方法,但我怎么通过NOW()方法,而不必对每类RTC对象的特殊情况Logger_SD ?

我Logger_SD.h看起来有点像这样,如果有帮助:

class Logger_SD { 
    public: // I don't quite understand the mechanics here, but it works great. 
     static Logger_SD* Instance(); 
     bool initializeSD(const uint8_t, const uint8_t disable_chip_select,DateTime* dt); 
     void msgL(LOG_LEVEL logLevel,const __FlashStringHelper *format, ...); 
     // ... 
    private: 
     Logger_SD(){}; 
     Logger_SD(Logger_SD const&){}; 
     Logger_SD& operator=(Logger_SD const&){}; 
     static Logger_SD* m_pInstance; 
     DateTime *_dt; 
     // ... 
}; 

我希望这是明确的。

下面是一个简单的例子:

class RTC1 { 
    public: 
    char now() { return 'A';} 
}; 
class RTC2 { 
    public: 
    char now() { return 'B';} 
}; 
class Logger { 
    public: 
    void ini(char f()) { logTime = &f ;} // this doesn't work 
    char (*logTime)(); 
}; 
void setup(){ 
    Serial.begin(57600); 
    RTC1 myRTC1; 
    Logger myLogger; 
    myLogger.ini(&myRTC1.now); 
    Serial.println(MyLogger.logTime()); // Should print 'A' 
    // now on a diffent kind of RTC for the same Logger 
    RTC2 myRTC2; 
    myLogger.ini(&myRTC2.now); 
    Serial.println(MyLogger.logTime()); // Should print 'B' 
} 

回答

1

myRTC1.now不能被转换为一个函数指针 - 它是一种类方法。您需要myRTC1的实例才能拨打now。你想要做的是不可能的。

什么可以代替做的是采取std::function

class Logger { 
public: 
    using LogFunc = std::function<char()>; // any function that takes no 
              // args and returns a char 

    template <typename F> 
    void ini(F&& f) { logTime = std::forward<F>(f); } 
    LogFunc logTime; 
}; 

然后你就可以分配正是如此:

Logger myLogger; 
myLogger.ini(std::bind(&RTC1::now, myRTC1)); 
myLogger.ini([&]{ return myRTC2.now(); });