wheemzy:
Essentially I want everything to be done (object instantiation and sensor readings) inside functions. Is this possible without significantly slowing performance?
Even if we are talking specifically about objects associated with physical devices, like LEDs, sensors, servos, motors, serial channels, and so on, there's still no definitive answer to that question.
Each C++ object is usually more than just a bunch of interface functions. It also stores data: some internal persistent state. Every time you destroy an object you lose its state. Every time you create an object, it begins with a clean state.
The question is: is the state of your object discardable? Can you afford to lose the state of your object between function calls? If you cannot, then you will have keep that object alive as long as you need it alive, even between function calls. But if you can afford losing that state (maybe you don't care about it, maybe your know how to restore it afterwards) then yes, you can just declare the object locally.
For example, let's say you have an object of some very primitive 'Led' class, which just attaches to some output pin and has on()
and off()
functions to set that pin to HIGH
and LOW
. The state of that object is probably just its pin number and it is effectively discardable. You can always recreate it and reattach it to the same pin. I'd even say that declaring such object locally is THE right thing to do.
A more complicated Led
class, which is, say, designed to support millis()
-based blinking/fading functionality for a LED will normally have much more elaborate state. It will store additional data responsible for handling timing/blinking/fading behavior. You won't be able to constantly destroy/create such objects, since that will completely disrupt their timing-based behavior.
The Servo
library does even more: when you create a Servo
object and attach it to a pin, this pin is registered in an timer-interrupt-based pulse generator. This generator is responsible for maintaining PWM signal at the pin, thus forcing the servo to hold its last set position. If you destroy the object, the pin is unregistered. Servo no longer receives the signal and no longer holds its position.
Things like that is what you have to keep in mind.
Some objects can be easily destroyed and recreated at any time. Some cannot and should not be.
wheemzy:
For instance, if I have a light sensor function, I want to instantiate the light sensor object inside the function each time it is called, and then of course the object is destroyed after each call.
If all your object does is instantaneous readings of sensor data, then this is most likely possible.
But if your object also performs some kind of internal batch-reading-and-buffering of the data, then it is a completely different story. You will lose all data buffered inside the object, unless you read it all before destroying the object.
Also, does your object perform some kind of initialization of the sensor in the constructor and de-initialization in the destructor? If so, then creating and destroying it every time in your function might be a bad idea.
These are the factors to consider. There might be many other factors.
To put it differently, one can say that there are at least two kinds of classes (there are more, actually):
-
Classes, which represent and reflect physical entities (LEDs, servos, motors etc.). They can also extend end enhance physical entities (make LEDs blink, make servos hold etc.). Object of such classes are intimately associated with their physical counterparts. They are joined at the hip, so to say. These object must exist as long as the physical entity exists (and as long as your program runs). You cannot just freely create and destroy such objects on a whim.
-
Classes, which represent interactive sessions with physical entities. They represent mere seances of communication, they represent communicative channels. A communication session begins and ends, while the entity continues to exist. Objects of such classes are created when you begin your communication session and destroyed when you end the session. Later you can do it again to start and end another session and so on.
The aforementioned Servo
class falls into the first category. Your sensor class most likely belongs to the second one.
In the end it all boils down to the same basic idea. If some piece of memory holds data that you will need for an extended period of time, then you have no choice but to keep that memory occupied as long as you need that data. If some piece of memory holds data that you need for only a short/limited period of time, then C and C++ offer you many different opportunities to optimize memory usage and make sure that memory is not wasted. It includes declaring objects locally, it includes manual management of dynamic memory, it includes "multiplexing" memory usage with unions and/or placement-new, it includes many other techniques.