Cast Operators

A long while ago I posted about how to implement New and Delete. This was just stuff I picked up around the traps but never actually used. Aha! So I've given it a try ... and I like it! It even caused me to discover cast operators.

Normal people don't think about building their own string class. But since you're reading this, maybe you do. As a simple test I needed a main sketch that could do this:
#include "String.h"

void setup()
{
Serial.begin(115200);
Serial.println("Program Start");
char stuff[] = "Christian";
String name1 = String(stuff); // from character array
Serial.print("name1: ");
Serial.println(name1);
String name2 = "Matthew"; // from string literal
Serial.print("name2: ");
Serial.println(name2);
Serial.println("Program Complete");
}

void loop()
{
}

To make this work, a String class is needed. Here it is, header file first:
#ifndef String_h
#define String_h

#include "NewDelete.h"

class String
{
private:
char* _string;
public:
String(char* input);
~String();
char* value();
};

#endif

... and String.cpp:

#include "String.h"

String::String(char* input)
{
char* in = input;
int length = 1; //always room for null terminator
while(*(in++)) length++;
_string = new char(length);
char* out = _string;
in = input;
while(*in) *out++ = *in++;
*out = '\0';
}

String::~String()
{
delete(_string);
}

char* String::value()
{
return _string;
}

Did I mention it used new and delete operators? NewDelete.h:
#ifndef NewDelete_h
#define NewDelete_h

//http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230935955

#include <stdlib.h> // for malloc and free

void* operator new(size_t size);
void operator delete(void* ptr);

#endif

NewDelete.cpp:

#include "NewDelete.h"

void* operator new(size_t size)
{
return malloc(size);
}

void operator delete(void* ptr)
{
free(ptr);
}

Two classes and a main sketch; we're done, right? Yeah, nah. There's this error message
In function 'void setup()': error: no matching function for call to 'HardwareSerial::println(String&)

I could see what was needed; some way for the println function to be able to receive my String class. At this point I went off and downloaded another String class from the Arduino site. I ran the example and his String was accepted by println with no fuss! So I had a working and non-working example of pretty-much the same class. First I ferreted through the HardwareSerial.h and HardwareSerial.cpp files - "they must have a println function for String!". No such luck. I saw HardwareSerial inherits from the Print class. Again no luck.

Out of ideas I began commenting out blocks of code from the downloaded String class to see how I could make it fail. And then I hit on it. A line that read:

operator char*() { return _string; }

What is that? It returns a string, which is what println is looking for. But what's an operator declaration doing using a data type? So there you are. It's a cast (conversion) operator declaration. You stick it in your String.h file. And immediately I can see a hundred uses for it. I'm going to get coding and blog some more later.

That is all.

Comments