Offline
Newbie
Karma: 0
Posts: 17
|
 |
« on: August 07, 2012, 01:13:00 pm » |
Hello, I'm actually a bit stuck. I need to have a pointer storing an instance of a derived class, but I can't figure out how to do so. Here some code followed by the error message which might help: RootClass.h #ifndef ROOT_H #define ROOT_H
#include <WProgram.h>
class RootClass { public: RootClass(); unsigned char currentValue; unsigned char valueCount; };
#endif
RootClass.cpp #include "RootClass.h"
RootClass::RootClass() { currentValue = 0; valueCount = 4; // some default value }
Derived.h #ifndef DERIVED_H #define DERIVED_H
#include "RootClass.h" #include <WProgram.h>
class Derived : public RootClass { public: Derived(); };
#endif
Derived.cpp #include "Derived.h"
Derived::Derived() : RootClass::RootClass() { currentValue = 0; valueCount = 5; // will overwrite the default value (actually works) }
sample.ino #include "RootClass.h" #include "Derived.h"
Derived a; Derived b;
RootClass* current; // this is supposed to point to an instance of Derived, changing while the program is running
void setup() { Derived a(); Derived b();
current = &a; // FAILS: cannot convert 'Derived (*)()' to 'RootClass*' in assignment }
// ...
What am I missing here? EDIT: Corrected name of constructor of Derived class. Added [solved] to subject. :-)
|
|
|
|
« Last Edit: August 07, 2012, 02:15:00 pm by sg80 »
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 311
Posts: 35474
Seattle, WA USA
|
 |
« Reply #1 on: August 07, 2012, 01:18:37 pm » |
class DerivedClass : public RootClass { public: RootClass(); };
Why is the DerivedClass constructor called RootClass? Derived a(); Derived b(); This is NOT how to create instances of the DerivedClass class (or the Derived class, for that matter). Loose the (); What am I missing here? You may need a cast, but, as the code posted won't even compile, its hard to say.
|
|
|
|
|
Logged
|
|
|
|
|
Des Moines, WA - USA
Offline
God Member
Karma: 21
Posts: 703
|
 |
« Reply #2 on: August 07, 2012, 01:25:42 pm » |
A valid pointer 'current' to instance 'a' once 'setup' is exited and the stack unwinds!
EDIT: An answer to the question: "What am I missing here?"
|
|
|
|
« Last Edit: August 07, 2012, 01:28:00 pm by lloyddean »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 17
|
 |
« Reply #3 on: August 07, 2012, 01:38:29 pm » |
Thank you very much! That already helped a lot! Now I've got it working with this code: #include "RootClass.h" #include "Derived.h"
Derived a; Derived b;
RootClass* current; // this is supposed to point to an instance of Derived, changing while the program is running
void setup() { Derived a; Derived b; }
void loop() { current = &a; Serial.println(String(current->valueCount)); }
// ...
Two questions: - As my constructors might need to have some parameters later on, how am I going to pass them (since I need to omit the '()')?
- Why can't I set the pointer in the setup-routine (where it might be well placed)?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 15
Posts: 1003
Arduino rocks
|
 |
« Reply #4 on: August 07, 2012, 01:56:52 pm » |
Two questions: - As my constructors might need to have some parameters later on, how am I going to pass them (since I need to omit the '()')?
- Why can't I set the pointer in the setup-routine (where it might be well placed)?
1. You only omit the parentheses when there are no arguments. Otherwise: myclass bob();
it looks like a function declaration called bob that takes no arguments and returns a myclass. On the other hand myclass bob(3);
could not be a declaration because there need to be type names inside the parentheses when declaring a function. 2. You can, as long as you don't use it before it's set.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 311
Posts: 35474
Seattle, WA USA
|
 |
« Reply #5 on: August 07, 2012, 02:00:43 pm » |
Why can't I set the pointer in the setup-routine (where it might be well placed)? Because the thing you are pointing to is a local variable that goes away (and gets deleted) when it goes out of scope. Then, you are left with a pointer that does not have the behavior you expect, since the place where ti points to no longer contains an instance of the class that you expect it to have.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 17
|
 |
« Reply #6 on: August 07, 2012, 02:02:59 pm » |
Why can't I set the pointer in the setup-routine (where it might be well placed)?
2. You can, as long as you don't use it before it's set. Which would happen - if I understand you right - because the first loop-call happens before the setup? I would never have guessed so. (?)
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 15
Posts: 1003
Arduino rocks
|
 |
« Reply #7 on: August 07, 2012, 02:05:12 pm » |
Why can't I set the pointer in the setup-routine (where it might be well placed)?
2. You can, as long as you don't use it before it's set. Which would happen - if I understand you right - because the first loop-call happens before the setup? I would never have guessed so. (?) No, it doesn't. Sorry I misunderstood why you were asking -- PaulS' answer is correct.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 17
|
 |
« Reply #8 on: August 07, 2012, 02:11:25 pm » |
Ah, now I understand! I've distinguished between the declaration and the construction - which was not correct. It works when I declare AND construct (in one step) the objects globally: Derived a; Derived b; RootClass * current;
void setup() { current = &a }
void loop() { Serial.println(String(current->valueCount)); delay(200); current = &b; Serial.println(String(current->valueCount)); delay(200); }
...works fine. THANKS again! :-)
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 311
Posts: 35474
Seattle, WA USA
|
 |
« Reply #9 on: August 07, 2012, 02:17:30 pm » |
...works fine. But doesn't prove anything. If you changed the valueCount field of a and b (by passing a value to the constructor or in setup), and saw that current->valueCount did indeed print differently as you change which object you point to, then you would have proven something. Serial.println(String(current->valueCount)); Don't make me come over there and slap you. There is absolutely no need to convert a char to a String so that the Serial.print() method can extract the char from the String to print it. A monumental waste of resources.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 17
|
 |
« Reply #10 on: August 07, 2012, 02:25:21 pm » |
Well, in the actual program (not the example I posted) the proof has been made; but yes, I'm aware that the example is insufficient concerning that. To justify myself for the waste of resources, I again need to refer to the difference between the example and my actual program, where not a Serial.print is called, but a function which expects a String. I apologize for that 
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 311
Posts: 35474
Seattle, WA USA
|
 |
« Reply #11 on: August 07, 2012, 02:44:08 pm » |
but a function which expects a String. Your function? Rewrite to accept a char *, and get rid of the String class. There is a major bug in the free() function that String uses that can corrupt your program much sooner than was originally thought, considering how many times String calls malloc() and free() (to increase the size of a String by one char). I apologize for that Don't apologize. Change it. 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 17
|
 |
« Reply #12 on: August 09, 2012, 11:59:09 am » |
Uh oh, you were right, I'm running into memory-problems due to the usage of the String-class.
Is that a bug to be fixed in near future or will I need to find a different solution by myself? Where can I get more information about that issue? I could only find some 2 or 3 year old information about something similar (which seems to be fixed meanwhile).
I'm not very used to handling strings using char-arrays or char*s. Is there any good tutorial out there?
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 311
Posts: 35474
Seattle, WA USA
|
 |
« Reply #13 on: August 09, 2012, 12:09:47 pm » |
Where can I get more information about that issue? http://arduino.cc/forum/index.php/topic,115552.0.htmlIs that a bug to be fixed in near future Not likely. or will I need to find a different solution by myself? Follow that thread. There is a fix available, but I'd still avoid the use of String. I'm not very used to handling strings using char-arrays or char*s. Is there any good tutorial out there? Probably. But, it isn't rocket science. Break the problem down into stages. Collect data, and store it in an array. When that works, move onto to parsing/searching the stored data. Keep in mind the need to reset the array and index at appropriate points.
|
|
|
|
|
Logged
|
|
|
|
|
|