Passing objects between custom classes (C++ OOP beginner!)

I've been working with Arduino for a while, but never took the leap into implementing OOP directly into my projects. I spend a lot of time working as a front-end web developer, and have become quite accustomed to thinking in OOP strategies (gotta love Javascript's looseness with types!). I was hoping to do a bit of basic OOP in my newest Arduino project by breaking important functionality down into separate classes for easier readability and modularity.

I'm able to create and use custom objects to handle specific tasks without much issue, but I'm having some trouble figuring out how to pass objects between these classes.

For a bit of context, I'm working on a wall plotter (sometimes called a "polargraph") that receives and executes basic G-code commands in order to draw shapes on a vertical surface with a pen. Therefore I have a Command class that represents the G-code command(s), which I want to pass around to other classes for processing. This Command is manipulated the following way:

  • The CommandParser tries to obtain serial data from a source (serial, SD card, etc) and turns it into a Command object for easier manipulation.
  • If a new Command has been retrieved I want to pass it to a CommandRunner, which will figure out what (and how) my robot needs to do to execute it in terms of motor movements.

The trouble I'm having right now is that the compiler is telling me that I have undefined references to my Command object, which I think might be because it doesn't see my initial Command object being initialized anywhere (since it should only be initialized when I explicitly try to get the command data from a source).

I kind of understand why this is a problem for the compiler, but I'm a little fuzzy on what I can do to fix it. Any ideas?

Hopefully from the attached code it'll be easier to understand than how I've described it! Keep in mind that it is probably a very simple problem coming from lack of experience with OOP in C++, so maybe my approach in general is flawed! (2.81 KB)

Rename "CommandParser.cpp" to "CommandParser.h" and then put the declaration of the static class member object in a new file called CommandParser.cpp:

#include "CommandParser.h"

Command CommandParser::command;

You will then want to #include "CommandParser.h" instead of "CommandParser.cpp"

It works, thanks! I will start doing some reading about the role of the header and cpp files now.

Some follow-up questions:

  • Why/how does this work?
  • Is it best practice to separate all function contents and appropriate variable definitions to the .cpp, and the "templates" to the .h files?
  • Is it possible to check whether this static command object is empty? In Javascript one might wrap a block of processing code in something like "if(object != null) { ... do stuff ... }" just to be safe. Maybe won't even be necessary with good design practices.