2015-02-10 58 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(); });