Note to SO. If I ask this question to AI I get a very similar output as the accepted reply. Without out all the questions about how I asked the question. Just sayin.
I am using this class for sensors. Each sensor has multiple capabilities (Temp and Humidity....). I need to access some of the properties of the sensor beyond the output values.
class Sensor {
public:
int id;
int sensorTypeVal;
const char* name;
SensorReading reading;
// Constructor to initialize Sensor with id, type, and name
Sensor(int id, int type, const char* name)
: id(id), sensorTypeVal(type), name(name) {} // Initialize reading with default constructor
// Constructor to initialize Sensor with id, type, name, and a SensorReading
Sensor(int id, int type, const char* name, const SensorReading& reading)
: id(id), sensorTypeVal(type), name(name), reading(reading) {}
// Method to update the sensor reading
void updateReading(const SensorReading& newReading) {
reading = newReading;
}
};
Fairly new to C++ so wondering what the normal approach is here. I found this Why should I use a pointer rather than the object itself? Which seems a level up from my question. I don't want to get into the sensor "wrapper" pattern and start duplicating properties across layers. Is it recommended to pass a ref to the sensor in on init, or move the sensor object inside the class and abstract it away?
Or is there another way to compose it?
Sensor is a class, there is a generally a library where the "sensor" is created such as Adafruit_AHTX0 aht; I can also create a ref like so Adafruit_AHTX0& raht = aht; Is it better to create the 'sensor' and the reference outside the class in the main program, or have private methods in the class that init the Adafruit_AHTX0 aht;
When you Adafruit_AHTX0 aht;
you create an instance of the class Adafruit_AHTX0
ie you allocate the memory for the class, and the default constructor is being called. The latter creates reference (alias) to the instance of the class Adafruit_AHTX0.
The place whe you create the instance of the class depends of the program needs but if has quite importan repercusions:
Scope | Memory Segment | Lifetime | Constructor Call | Access |
---|---|---|---|---|
Global | Global/Static segment | Entire program duration | Before main() starts |
Accessible across the program (if not static ). |
Local (Stack) | Stack memory | Within the enclosing block | When the block or function is entered | Limited to its function/block. |
Dynamic (Heap) | Heap memory | Until explicitly deallocated | When new is called |
Accessible via pointers. |
Static (Local) | Global/Static segment | Persistent across the program (initialized only once) | First time the block is executed | Limited to its function/block. |
Static (Global) | Global/Static segment | Entire program duration | Before main() starts |
Accessible across the program. |
Small embedded targets have their specific needs - nor necessary following the best practices for "normal" big computers. It is very broad topic far beyond a simple SO answer.