The playground hasn't been updated to have information about using the print class with Arduino 1.0+
Is the virtual void write(const uint8_t character); function necessary if you have the virtual void write(const uint8_t *buffer, size_t size); function? With the library I have made, having the cstring version is far more helpful.
depends on (1). I am assuming based on the compiler messages that the void simply needs to be changed to size_t. I have done this, however I now get an error: error: invalid use of 'class Print'. At the moment, both of the actual functions are empty, but they are implemented:
The playground hasn't been updated to have information about using the print class with Arduino 1.0+
What do think needs to be changed?
Is the virtual void write(const uint8_t character); function necessary if you have the virtual void write(const uint8_t *buffer, size_t size); function?
Since the write() array method calls the write() character method, I think the write() character method is needed.
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--) {
n += write(*buffer++);
}
return n;
}
With the library I have made, having the cstring version is far more helpful.
What cstring version?
Any help would be appreciated
Both of those methods are defined to return a value. Neither does. That is a problem.
I think you need to post your header file, too.
Perhaps looking at another class that derives from Print, like Stream, would prove beneficial.
Well really just that they now return a type, and what it is they are supposed to return.
Thanks for confirming that. (oh, and by cstring one, i meant the version which uses the buffer, as opposed to the single character one - maybe that was a poor choice of words).
Ahh yes, I changed the type from void, but forgot about the return type. I now get this:
BasicFunctions.pde:-1: error: cannot declare variable 'graphic' to be of abstract type 'gLCD' E:\Thomas\Downloads\Programs\EXE\arduino-1.0\libraries\gLCD/gLCD.h:193: note: because the following virtual functions are pure within 'gLCD': E:\Thomas\Downloads\Programs\EXE\arduino-1.0\hardware\arduino\cores\arduino/Print.h:49: note: virtual size_t Print::write(uint8_t) BasicFunctions.cpp: In function 'void loop()': BasicFunctions.pde:-1: error: invalid use of 'class Print'
So, you meant c string, not cstring. A cstring is an abomination from Microsoft that you really don't want to use on the Arduino.
The virtual keyword in the Print class means that any class that derives from it MUST implement this defined, but not implemented, function. You should not be declaring write virtual in your class. Virtual functions make a class abstract, and abstract classes can not be instantiated. Only classes that derive from an abstract class can be instantiated.
It's pretty easy. First, go to the *.h file and go to the section where you defined the name of your class after the word "class". Then, change it to this:
Ahh, I have worked it out. I was calling Print() in the sketch file not print(). Also, it wont compile unless both of these are in the header:
virtual size_t write(const uint8_t *buffer, size_t size);
virtual size_t write(const uint8_t character);
It works with only the c string (i remembered the space ;)) version in the cpp file though, so both don't need to be implemented, just defined. It would appear then that the playground is correct.
Good. I was thinking of pure virtual functions, where the function is defined but not implemented by a class, and must be implemented by the subclass. Sorry to have mislead you.
PaulS:
The virtual keyword in the Print class means that any class that derives from it MUST implement this defined, but not implemented, function. You should not be declaring write virtual in your class. Virtual functions make a class abstract, and abstract classes can not be instantiated. Only classes that derive from an abstract class can be instantiated.
That's only true if it says the function = 0. Otherwise, you can override it if you want to. The virtual in the derived class is technically not necessary, but it's not harmful either (apart from a small loss in efficiency). Try out this sketch.
class pureVirtual {
public:
virtual void myFunc() = 0;
};
//pureVirtual pur; // error
class hasVirtual {
public:
virtual void g();
};
void hasVirtual::g() {
Serial.println("HasVirtual::g()");
}
hasVirtual hasVirt; // no error
class derived : public hasVirtual {
void g();
};
void derived::g() {
Serial.println("derived::g()");
}
derived derv;
hasVirtual* hasVirt1 = &hasVirt;
hasVirtual* hasVirt2 = &derv;
void setup() {
Serial.begin(115200);
hasVirt1->g(); // prints "HasVirtual::g()"
hasVirt2->g(); // print "derived::g()" even those hasVirt2 is of type
// hasVirtual -- that's the magic of virtual
}
void loop() {}
In the end, both of those two functions need to be in the header, and in the cpp file. As I am overwriting the original string version, I have left the character version blank, and all is working very well! My library originally used the String class to print anything using a function I called Print. However I don't like the String class, and have finally got around to using the proper print library for it.
PaulS:
You should not be declaring write virtual in your class. Virtual functions make a class abstract, and abstract classes can not be instantiated.
In addition to what WizenedEE about that only being true if the virtual class is "= 0" (which you acknowledge later PaulS) the question arises about the "virtual" keyword in derived classes. One debate about it here:
Apparently it is not required in the derived classes, however some compilers (but not the Arduino one) might issue a warning if it isn't there.
Personally I think it is good form to use it as a form of documentation, to make it clear that you know you are implementing a virtual method.
TCWORLD:
In the end, both of those two functions need to be in the header, and in the cpp file.
If you haven't already you might want to add this to the derived class:
using Print::write; // pull in write(str) and write(buf, size) from Print
That lets you call certain forms of write in your derived class that otherwise you couldn't.