views:

86

answers:

4

Hello!

I have a few classes (heat, gas, contact, pressure) inheriting from a main one (sensor).

I have a need to store them in a vector<Sensor *> (part of the specification).

At some point in time, I need to call a function that indiscriminately stores those Sensor *. (also part of the specification, not open for discussion)

Something like this:

for(size_t i = 0; i < Sensors.size(); ++i)
    Sensors[i]->storeSensor(os) //os is an ofstream kind of object, passed onwards by reference

Where and how shall storeSensor be defined?

Is there any simple way to do this or will I need to disregard the specification? Mind you, I'm a beginner!

Thanks for your time!

+1  A: 

storeSensor should be declared virtual in Sensor (and any other class that may be further inherited). This will make sure that the call

Sensors[i]->storeSensor(os);

will pick up the correct method.

You only need to redeclare storeSensor in any class that has a different implementation for that method than the base class.

patros
I argued with a coworker about this once but never bothered to find the answer - is it in fact necessary to label the method virtual in a derived class, if the base class already has it virtual?
reuscam
@reuscam No, it isn't.
anon
+4  A: 

You need to make it a pure virtual function, which you then implement in each of the derived classes. The implementation can be pretty simple:

class sensor {
   ....
   virtual void storeSensor( ostream & os ) = 0;
};

class heat : public sensor {
   ....
  void storeSensor( ostream & os ) {
     os << * this;
  }

};

class light : public sensor {
   ....
  void storeSensor( ostream & os ) {
     os << * this;
  }

};

This assumes you have defined a suitable operator<< for each of your classes. If not, you need to write the specific sensors member variables explicitly. And that is the easy bit - the difficulty starts when you want to read the sensors back in again :-)

anon
`sensor::storeSensor()` doesn't *have* to be pure virtual, right?
egrunin
why not just declare openator<< virtual, implement it in each sensor,, and let storeSensor a method of sensor?
CharlesB
@CharlesB You cannot declare op<< virtual for sensors, as its LHS operand must be a stream, not a sensor.
anon
@egrunin It has to be virtual, but not possibly not pure. Still, it's normally a good idea to make base class virtual functions pure.
anon
How is it difficult to read them back in? In my txt file, the sensors' type (gas, heat, etc) is stored. Simple switch case, I believe.
Francisco P.
@Framcisco That's a naive scheme which isn't suitable for real applications. To start with, you need to modify the switch every time you add anew sensor type. also, most C++ types contain other types and relationships, which are hard to encode and harder still to decode. Of course, it can be done, but it isn't so simple as you seem to think.
anon
+2  A: 

If StoreSensor is the same functionality for all types of sensors, define it in the base class as virtual, and be done with it.

If its differs depending on each type of sensor, and it is guaranteed to differ for all sensors, then define it as pure virtual in the base class, and override it in the derived sensor classes.

If it can differ, but is not guaranteed to, follow step 1, and then override in the derived classes when needed.

reuscam
+1  A: 

If all the subclasses use storeSensor() and it always takes the same parameter, you can just declare it in the parent class Sensor. Then store the pointer as a ofstream pointer in the parent Sensor class.

I really don't see why it needs to be virtual if it is always the same.

Michael Ozeryansky