"Operator? Operator!"

Everything is evolving. I start out with simple concepts and get to a point where I realise there must be a better way. I read, research, write lots of test code and then make a step forward in my Arduino (C++) coding method. Here's how I arrived at operator overloading in Arduino.

While working on the Wesley Clock, I got the entire "Weasel" almost complete before I ran into a problem. I could extract serial data from the GPS. I "tokenized" it to pull out the individual data for latitude, longitude, time, etc. and then found I needed to correct the UTC time for my time zone, and couldn't. Most Arduinians at this point would reach into the cupboard and pull out the atoi() function and be done. But not this pedant. I'm coding for the learning here; I'm bare-metal coding as far as possible. That means I write all my own stuff including parsing strings to integers.

The first logical step is to write a stringToInt() function. That I did quickly. The next step was to prove it works. I went off on a tangent for a few weeks to develop a test-driven development (TDD) methodology for my Arduino environment. (I'm back from that walkabout and will document it soon.) I then realised I wasn't abstracting things far enough. I was converting the hours-since-midnight from text to a string then adding 10. Great! But what happens after 2pm GMT? I need the date to roll over to the next day. I hadn't accounted for that!

I spent a while on a Time class, then a Date class, then a DateTime class. All interesting stuff dealing with leap years and the different number of days in each month and so on. When I came back to the need to add 10-hours to the time that came from the GPS I could do this:

DateTime now(gps.time()); //parses time as a string
now.add(10, HOURS); //HOURS from the TimeUnits enumeration

OK sweet. It looks like I've made it. But the very next thing that I tried to do was compare two of my classes for equality.

if(now == then) ...

... and we find that the DateTime class hasn't defined how the == operator works. "I know this! I've done operator overloading! This is good C++! Oh, I wonder if it works on Arduino?" Well thankfully it's fairly uneventful. Look up any C++ reference on operator overloading and apply it in your classes. Here's my example Int class to show you what I mean.

Main sketch:

#include "Int.h"

Int one(1);
Int two(1);

void setup()
{
Serial.begin(115200);
Serial.println(one.value());
Serial.println(two.value());
if(one == two) Serial.println("Same");
else Serial.println("Different");
}

void loop()
{
}

Int.h

#ifndef Int_h
#define Int_h

#include "WProgram.h"

class Int
{
public:
Int(int value);
int value();
boolean operator == (Int &other);
private:
int _value;
};

#endif

Int.cpp

#include "Int.h"

Int::Int(int value)
{
_value = value;
}

int Int::value()
{
return _value;
}

boolean Int::operator == (Int &other)
{
if(_value == other.value()) return true;
return false;
}


So there you go. Operator overloading in Arduino is no biggie. The only complication I can see on this is that if the object doesn't expose it's value so easily (other.value()) you'll need to access private members to do the equality; thus you'll need to define your operator as a friend function. I won't cover that here.

Asside:
I'm wary that Arduino doesn't implement new and delete. It makes me feel that there must be other important parts of C++ that are missing too. I've blogged about a workaround for new and delete and I'm now emboldened to go and do a full-blown-C++ experiment. I'm going to build a queue for Arduino and see what happens.

That is all.

Comments