I am trying to understand the internals of https://github.com/vshymanskyy/TinyGSM/tree/master/src and am confused with how the classes are constructed.
In particular I see that in TinyGsmClientBG96.h they define a class that inherits from multiple templated parent classes.
class TinyGsmBG96 : public TinyGsmModem<TinyGsmBG96>,
public TinyGsmGPRS<TinyGsmBG96>,
public TinyGsmTCP<TinyGsmBG96, TINY_GSM_MUX_COUNT>,
public TinyGsmCalling<TinyGsmBG96>,
public TinyGsmSMS<TinyGsmBG96>,
public TinyGsmTime<TinyGsmBG96>,
public TinyGsmGPS<TinyGsmBG96>,
public TinyGsmBattery<TinyGsmBG96>,
public TinyGsmTemperature<TinyGsmBG96>
Fair enough. If I look at one of these, for example TinyGsmTemperature, I find some confusing code.
It looks like the static cast is in place so the we can call the hardware agnostic interface getTemperature() and use the implementation defined in TinyGsmBG96.
- Why not use function overriding in this case?
- What is the thinking behind this implementation?
- Is this a common pattern in c++?
template <class modemType>
class TinyGsmTemperature
{
public:
/*
* Temperature functions
*/
float getTemperature()
{
return thisModem().getTemperatureImpl();
}
/*
* CRTP Helper
*/
protected:
inline const modemType &thisModem() const
{
return static_cast<const modemType &>(*this);
}
inline modemType &thisModem()
{
return static_cast<modemType &>(*this);
}
float getTemperatureImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED;
};