So in C++, I can write code that extends a class, right? So in theory I could write a Serial.print method that extends the existing code to accept new argument types, like a float or prog_char[] (string in flash)? What would that look like? (the C++ wrapper extend the class for floats, not the internal code to actually print a float.)
To extend the class, add any new methods in the puplic section, I have added one for floats at the bottom.
Then write the method in HardwareSerial.cpp following the style of the exisiting methods.
void HardwareSerial::print(float n)
{
// your code here
}
So in C++, I can write code that extends a class, right? So in theory I could write a Serial.print method that extends the existing code to accept new argument types, like a float or prog_char[] (string in flash)? What would that look like? (the C++ wrapper extend the class for floats, not the internal code to actually print a float.)
To clarify, you're wanting to extend the class (at compile-time) without editing the original source code files?
In terms of how 'Serial' is implemented for Arduino (it's an instance of the 'HardwareSerial' class) I'm not sure you could "retroactively" extend the already created object. I guess you could sub-class 'HardwareSerial' and then replace the current value of 'Serial' with an instance of your new sub-class.
If it was Python you could add a new method to the instance on the fly--I have no idea if this is possible in C++ or not...
you're wanting to extend the class (at compile-time) without editing the original source code files?
Yes. Ideally, hardwareserial.cpp wouldn't change, and code that uses hardwareserial wouldn't have to include any floating point code (or reference pgmmem.h, for that functionality.) I want to add functionality to SOME programs without causing "bloat" everywhere.
why not derive a new class from the HardwareSerial base class and add the print float method. Use the new class only in those programs that need floats in addition to all the inherited functionality.
class HardwareSerialFloat: public HardwareSerial
{
public:
HardwareSerialFloat(uint8_t); // constructor for the class that inherits HardwareSerial methods
void print(float); // added print method for floats
};
So basically this really works (version 0013 @ linux), but one detail still disturbs me (let's say my class is called myClass):
For some reason I don't understand, I have to call the (inherited) function myClass.begin($BAUDRATE) function from void setup()... it is not working to call this in the construcor of myClass (it compiles fine, but just doesn't to anything)
... Does anybody got an idea why this is the case? Maybe one instance of HardwareSerial (Serial?) is built automatically by the arduino framework or something?
The built-in copy of main() calls an Arduino initialization function called init() before setup() and loop(). However, constructors of globals are executed before main() begins, and so there's a problem with this.
Personally, I'd almost recommend a change to main() to deal with this better, but it specifically relies on the order of files linked. Make a small class with a constructor that calls init(), and make a global instance of that small class. I believe the .o file that includes this global instance needs to be linked first to make sure the small class's constructor's init() call happens before constructors of other global instances, but this trickery is up to the linker.