I completed converting a long sketch to fully encapsulated OPP and it runs great. Now I want to break it out into several .cpp and .h files.
When I do this, the .cpp which has calls to class objects throws a not declared in scope error. Let me try to boil down the code to just a few lines to illustrate the problem.
// .iso file contains (along with a lot of other stuff)
#include "Duty.h"
Duty Ref(RefIn); // constructor
// Duty.h contains the full class declaration and includes the method CalcDuty
// .iso also contains the following line within an lcd output function
lcd.print(Ref.CalcDuty());
// So far, everything is great...
// Now, when I take the lcd output function out of the .iso and move it to a myLCD.cpp and supporting
// myLCD.h I get the error:
// error: 'Ref' was not declared in this scope
// lcd.print(Ref.CalcDuty());
// ^
// myLCD.cpp contains
#include "Duty.h"
It is not the class Duty that is not in scope, it is the object of the class, Ref
That is constructed in the .iso.
I am thinking I need some sort of forward declaration to the object but have not figured out a form of
such forward declaration that helps here.
Say we have a class with methods in a .h file, constructors for objects in a .iso file, and a function in a .cpp file. The class is Myclass which includes a method DoThis. The constructor creates an object, Myobject1. The function call in the .cpp file calls Myobject1.DoThis(); Now Myobject1 is out of scope in the.cpp file. How do I forward reference it, and the six other methods which are out of scope in this .cpp file, such that this can compile. Of course, keeping everything in one file works fine, but it's sloppy.
What is a .iso file? Do you mean .ino, an Arduino sketch?
You can't use the name a global object instance that is declared in a .cpp file without declaring the name of the extern global object instance in the .ino file:
#include "Duty.h"
extern Duty Ref; // There is a global instance named 'Ref' in some .cpp file
void function()
{
Serial.print(Ref.CalcDuty());
}
If you declare the object instance 'extern' and don't declare it somewhere, you will get an 'undefined reference' error in the linker.
Or you put it in your .h file as an extern and your .cpp file as the real thing. Then, when the .h file is #included in your .ino file, or wherever its needed, its automatically there as well.
Basic .h .c/.cpp file usage. Things everyone needs to know to use the class and/or library goes in the .h file. All the "guts" go in the c/.cpp file.
Typically in Arduino-land, you tie this all together in your .ino file.
If your project gets really complicated and you need to share some globals across a bunch of files including possibly your .ino file. You can make up a globals.h and do the externs of those in there. Then a globals.cpp for the actual globals. Then globals.h can be #included wherever you need them.