Long time software engineer – Arduio newbie, having a declaration syntax problem.
Can someone point me to code that declares instances of a class within another class? Let’s say I’m writing a library class called Elephant, and want each instance to have a local instance of Trunk and four local instances of Foot. When I declare them in the class declaration (e.g. the .H file) I get compiler errors.
I want to instantiate them in the encompassing classes’ constructor and make them global to the instance. I looked through the libraries that come with the board and didn’t see any examples of this (plenty of local integers and arrays, but no class objects).
That looks like what I need, and it compiles, but I can't get my (slightly more complex) example to compile, so I'll post it.
I have two classes, MGLED7 which suports 7-segment numerical LED displays, and MGLED73 which supports a 3-digit cluster of LED displays. An MGLED73 instance needs to have 3 local instanceds of MGLED3 (one for each physical display). Code attached (see '??' markers for the lines in question).
The compile errors are:
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp: In constructor 'MGLED73::MGLED73(int, int, int, bool)':
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp:7: error: no matching function for call to 'MGLED7::MGLED7()'
C:\Program Files\Arduino\libraries\MG/MGLED7.h:10: note: candidates are: MGLED7::MGLED7(int, bool, bool)
C:\Program Files\Arduino\libraries\MG/MGLED7.h:8: note: MGLED7::MGLED7(const MGLED7&)
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp:7: error: no matching function for call to 'MGLED7::MGLED7()'
C:\Program Files\Arduino\libraries\MG/MGLED7.h:10: note: candidates are: MGLED7::MGLED7(int, bool, bool)
C:\Program Files\Arduino\libraries\MG/MGLED7.h:8: note: MGLED7::MGLED7(const MGLED7&)
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp:7: error: no matching function for call to 'MGLED7::MGLED7()'
C:\Program Files\Arduino\libraries\MG/MGLED7.h:10: note: candidates are: MGLED7::MGLED7(int, bool, bool)
C:\Program Files\Arduino\libraries\MG/MGLED7.h:8: note: MGLED7::MGLED7(const MGLED7&)
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp:10: error: expected primary-expression before ':' token
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp:10: error: expected `;' before ':' token
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp: At global scope:
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp:39: error: expected declaration before '}' token
<<
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp: In constructor 'MGLED73::MGLED73(int, int, int, bool)':
C:\Program Files\Arduino\libraries\MG\MGLED73.cpp:7: error: no matching function for call to 'MGLED7::MGLED7()'
Start fixing the errors from the top down. This one should be dirt simple to fix. You are trying to call a no argument constructor for the MGLED7 class in the MGLED73 class. There are no versions of the constructor that take no arguments. So, quit trying to call the no argument version, or create a no argument version that can be called.
That's the part I don't understand. I don't see where in the code I'm calling a no-argument constructor. The only two references to MGLED7 in the MGLED73 code are:
private:
MGLED7 LED0,LED1,LED2; //?? Declaring individual LED objects
Which is the declaration, and shouldn't be referencing a constructor or requiring constructor parameters, and
(fromat from this forum) in which I am using the proper parameters.
If I use the code I started with in the MGELD73 constructor
//Original code
LED0 = new MGLED7(pin0,activeHigh,true);
LED1 = new MGLED7(pin1,activeHigh,true);
LED2 = new MGLED7(pin2,activeHigh,true);
I get exactly the same error.
AND, if I comment out all constructor references and just declare the objects in the class declaration (first code snipped above), I STILL get that error.
I'm out of time this morning, but will try to deconstruct it into just the lines that fail this weekend. Thanks.
The only two references to MGLED7 in the MGLED73 code are...Which is the declaration, and shouldn't be referencing a constructor or requiring constructor parameters
You are mistaken.
MGLED7 someObject;
IS creating an instance of the class MGLED7 in the variable someObject. Since there are no arguments defined, a no argument constructor is required to create the instance.
Now, a statement like:
MGLED7 *somePtr;
is simply declaring that there is a variable, somePtr, that will, possibly, in the future, point to an instance of the MGLED7 class. That would not invoke the constructor. But, that is not what you have,
If I use the code I started with in the MGELD73 constructor...I get exactly the same error.
You are confusing objects and pointers to objects (usually referred to as instances).
AND, if I comment out all constructor references and just declare the objects in the class declaration (first code snipped above), I STILL get that error.
Of course you will.
You need a no argument constructor that simply creates the objects, and an begin() method that initializes them with useful data, like the Serial class does.
Got it; thanks. So the constructor is called implicitly when the enclosing class is instantiated. I could declare a pointer only and instantiate it later, but I seem to remember CPP requring me to then dereference it every time I used it. But creating an overloaded constructor with no params then calling a sepperate initializer worked great.
Thanks for your time!
I'm trying to do something very similar to the original question but I'm having some problems.
Questions:
Is the approach mentioned in the previous responses still valid for Arduino IDE 1.6.12? I ask this question because different forum posts from others experiencing similar issues alluded to an issue with the compiler itself, but those were very old posts.
Can someone please provide a more specific example of how to implement the solution mentioned in the previous responses in this post, showing exact syntax? That would be very helpful for me and for any other newbies who wrestle with this situation.
Do you get extra karma points for being a confrontational jerk??!
I think my question was pretty clear, big mouth: Can anyone please show a specific example of how to implement the previous abstract solution? If you are not bright enough to figure that out or bright enough to provide a coherent and useful response, then why don't you go watch some Gilligan's Island reruns or maybe spend your time on a different forum where your abuse is welcome? Thanks for nothing. I've heard others brag about the friendly support and help they'd received on this forum, but I'm pretty sure they were not referring to you. Oh, and have a nice day. Flame off.
MattGr:
Can someone point me to code that declares instances of a class within another class?
Sure!
I want to instantiate them in the encompassing classes' constructor and make them global to the instance.
what? If it's global, it's not an instance variable.
In any case: you use the colon for this. You can also use the colon syntax for primitive types. I do this all the time - it's a great way to assign pins to networks of objects. Remember that you don't talk to the pins in the constructor. This must be done via the setup method, which is invoked after hardware initialization is done. The constructor is purely for setting up the numbers to be used. I like to give each of my objects their own setup and loop, even if those methods do nothing.
class A {
const int pin;
A(int attachPin) : pin(attachPin) {
// other constructor code goes here
}
void setup() {
pinMode(pin, INPUT_PULLUP);
}
};
class B {
A myA;
B(int a_attach) : myA(a_attach) {
// other constructor code goes here
}
void setup() {
myA.setup();
}
};
B quux(7); // attach quux to pin 7
void setup() {
quux.setup();
}
JoelDude:
I'm trying to do something very similar to the original question but I'm having some problems.
Rather than being so vague, and necro-ing a four and a half year old thread, don't you think it would've been simpler to state your exact problem, and post your exact code?
PaulMurrayCbr - Fantastic! Thank you so much for your concise, understandable examples, which now make this entire post more useful to others who read it.
AWOL - No, I don't really think it would have been easier to post my code as a new question, but thank you for suggesting. It would have been easier, however -- and would have raised fewer peoples' blood pressure including my own -- to ponder deeply before asking my question and then ask it clearly and unambiguously. Maybe I should run my questions past Phil Donahue before posting here, which was a splendid suggestion shared by one of the earlier responders, LOL.