Recommended way to create an inversion of a bool value returned by a class with same interface in C++? - c++

I have a use case that involves collections of sensor objects that return a bool (indicating the state of the sensor). In some cases the collection object is interested in the inverse of a the sensor value, but I want to use the same interface for both cases so that the collection doesn't need to track this. An example might be
Result = sensorA | not(sensorB)
where the the value of sensorA and not(sensorB) are accessed using the same interface. I've come up with a couple of solutions for this, none of which seem as simple as I originally expected the problem to be.
Firstly, I can realize the goal by creating another class that inherits from the same base interface and performs the translation. However this seems a little clunky as I have to instantiate a inverting object for each sensor:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class ObservedSensorBase
{
public:
virtual bool getState(void) = 0;
protected:
ObservedSensorBase() { inverted = new InvertSensor(this); }
};
class ConcreteSensor : public ObservedSensorBase
{
public:
ConcreteSensor(bool state) :mState(state) {}
bool getState(void) { return mState; }
private:
bool mState;
};
class InvertSensor : public ObservedSensorBase
{
public:
InvertSensor(ObservedSensorBase *sensor) :mSensor(sensor) {}
bool getState(void) { return !mSensor->getState(); }
private:
ObservedSensorBase *mSensor;
};
int main()
{
ConcreteSensor sensorA(true);
InvertSensor notSensorA(&sensorA);
vector <class ObservedSensorBas*> sensors;
sensors.push_back(&sensorA);
sensors.push_back(&notSensorA);
for (class ObservedSensorBase* it : sensors)
{
cout << it->getState() << endl;
}
return 0;
}
Prints:
1
0
Ideally I'm looking for the original concrete sensor class to be able to return the inverted functionality. I can do this if I add a public class to each concrete sensor:
class ConcreteSensor : public ObservedSensorBase
{
public:
ConcreteSensor(bool state) :mState(state),inv(this) {}
bool getState(void) { return mState; }
class InvertSensor inv;
private:
bool mState;
};
...
sensors.push_back(&sensorA.inv);
Prints
0
but this seems a little cumbersome, as its a new variable in each concrete class. I can't add it to the base class, as InvertSensor inherits from the base, so InvertSensor isn't fully defined and can't be instantiated (at least I haven't been able to do so).
The other approach I've investigated is using an object factory:
ObservedSensorBase *invertFactory(ObservedSensorBase *sensor)
{
static map<ObservedSensorBase *, ObservedSensorBase *> m;
// Create an instance of the inverter for this object if it doesn't already exist
if (m.find(sensor) == m.end())
{
m[sensor] = new InvertSensor(sensor);
}
// Provide the inverting object for the passed sensor
return m[sensor];
}
...
sensors.push_back(invertFactory(&sensorA));
Prints
0
Is there another solution that I'm missing? Ideally something inherent in the class that each concrete instance can inherit from, but at this point it's become a bit of an intellectual challenge as well :)
--- EDIT ---
Thanks for the comments so far.
To clarify the objective better, this is for a little project for an Arduino to control signals on a model railroad. For the purposes here, assume that the signals can only show green and red. They show red when any track occupancy circuit or switch orientation that the signal is 'protecting' against indicates its unsafe for a train to proceed (and green otherwise).
Both the track detection and switch orientation objects would be concrete instances of the base sensor, but it's the switch orientation that creates this use case. If we have two signals, each of which is 'protecting' the two approaches to the two-track end of a single switch, one signal will want to use the switch orientation sensor 'as-is', and the other will want to use the inverted sensor value (to represent which way the switch is thrown).
I'm wanting to be able to invert the sensors' state representation when loading the into the signal object that holds them to avoid having to store a separate 'invert this signal' indication in the signal object, or manually instantiate a separate object that performs the inversion.
So something like
Signal1 protects SensorA (trackA) and Switch B
Signal2 protects SensorC (trackC) and not(SwitchB)
Here is an example of the signal (a container of sensors that just ORs them all together) e.g.
class Signal
{
public:
void protect(class ObservedSensorBase *sensor) { mSensors.push_back(sensor); }
void periodicLoop(void)
{
bool anyProtectedSensorActive = false;
for ( auto it = mSensors.begin();
it != mSensors.end() && !anyProtectedSensorActive;
++it)
{ anyProtectedSensorActive |= (*it)->getState(); }
if(anyProtectedSensorActive)
{ /* set Signal Red */ }
else
{ /* set signal Green */ }
}
private:
vector <class ObservedSensorBase*> mSensors; // protected sensors
};
...
Signal signal1;
Signal signal2;
signal1.protect(&sensorA);
signal1.protect(&sensorB);
signal1.protect(&sensorC);
signal1.protect(&notSensorB);
However, after playing with #Jason C's recommendation to put something in the base class (which I couldn't get working prior to asking the question, or after his suggestion) it occured to me that I could create
// Invert Sensor and ObservedSensorBase are declared as above...
class InvertedSensorBase : public ObservedSensorBase
{
public:
InvertedSensorBase() : inverted(this) {}
class InvertSensor inverted;
};
// Change the inheritance of the concrete observer
//class ConcreteSensor : public ObservedSensorBase
class ConcreteSensor : public InvertedSensorBase
And now SensorA.inverted seems to fit the bill very well.
Of course, since this is mostly a side project to return to C++ and learn C++11 after a long absence, if anyone has alternate suggestions about any point, I'd be more than happy to see them.

If you want a really no-effort solution you could store pair<ObservedSensorBase*,bool>'s in your container, where the boolean is whether you want to invert or not, and just have your logic invert the value based on that bool:
typedef pair<ObservedSensorBase *,bool> SensorWithFlag; // ...or something
vector<SensorWithFlag> sensors;
sensors.push_back(SensorWithFlag(sensor1, true)); // invert
sensors.push_back(SensorWithFlag(sensor2, false)); // don't invert
// then later when you use it, say 'n' is an index:
bool state = (sensors[n].first->getState() != sensors[n].second);
But if not, I suppose you could do the inversion in the base:
class ObservedSensorBase {
...
public:
void setInvertState (bool invertState) {
invertState_ = invertState;
}
bool getState () {
return invertState_ != getState_(); // != is xor
}
protected:
virtual bool getState_ () = 0;
private:
bool invertState_;
};
Then all subclasses implement getState_ instead of getState, and all have the ability to have their results inverted by setting setInvertState(true).
But this seems weird. Perhaps you could add some more details about how your containers are using these values. I feel like there may be a better way in general to structure your program and algorithms.
Another option is to use your "inverting filter" option but manage it in the base:
class ObservedSensorBase {
...
public:
ObservedSensorBase (...) : inv_(this) { ... }
InvertSensor * inverted () { return &inv_; }
private:
InvertSensor inv_;
};
Then you can just add mySensor->inverted() to your container when needed. This has the following caveats:
Do not call any virtual methods of ObservedSensorBase from InvertSensor's constructor.
Do not call any methods of InvertSensor that may lead to virtual base methods being called, from ObservedSensorBase's constructor.
Pointer returned by inverted() is invalidated when sensor is deleted.
The first two points are important because this won't be fully constructed yet when constructing subclasses.
This way, every sensor automatically has an inverted version of itself that comes along with it, and you don't have to manage them manually.
Yet another solution is to create wrappers around sensor objects, but keep them simple and store them directly in containers instead of storing pointers to them, to keep memory management easier. For example:
class SensorValue {
public:
SensorValue (ObservedSensorBase *s, bool invert)
: s_(s), i_(invert) { }
bool getState () { return i_ != s_->getState(); }
ObservedSensorBase * sensor () { return s_; }
private:
ObservedSensorBase *s_;
bool i_;
};
// then later, let's say you have some sensors:
ObservedSensorBase *sensor1 = ...;
ObservedSensorBase *sensor2 = ...;
// you can have containers like this:
vector<SensorValue> collection1, collection2;
// and you can use normal/inverted states as needed:
collection1.push_back(SensorValue(sensor1, false)); // normal values
collection1.push_back(SensorValue(sensor2, false));
collection2.push_back(SensorValue(sensor1, true)); // and inverted
collection2.push_back(SensorValue(sensor2, true)); // at the same time
// if you ever need the sensor object itself you can use SensorValue#sensor:
for (vector<SensorValue>::iterator i = collection1.begin();
i != collection1.end(); ++ i)
{
bool state = i->getState(); // normal or inverted, transparent to us here
ObservedSensorBase *sensor = i->sensor(); // can be used for whatever.
// note that i->getState() != i->sensor()->getState() if we're
// using an inverted SensorValue.
}
// and they aren't pointers, you can just do this with no leaks:
collection1.clear();
collection2.clear();
// although of course you still do this for sensor cleanup:
delete sensor2;
delete sensor1;
This is sort of conceptually like your inverted sensor object approach except SensorValue isn't an ObservedSensorBase, it's lightweight and cheaply copyable, and you can just store them directly in containers instead of passing around pointers.
It's very similar to storing e.g. pair<ObservedSensorBase*,bool> (where you store sensor and invert flag) in your containers instead, except unlike pair it gives you a convenient getState() member, and has some semantic meaning.

Related

can i cast a template instance with arg uint to same template instance with arg int - is it compliant - to which standard?

Plz check following c++ code: (nothing special, should be compliant to c++ 2nd edition from 1991)
class C
{
// also defines all the methods called in template method below with the obvious name and args.
public: template<typename TEnum> void SetNullableEnumValuePtr(CNullable<TEnum>* aEnumPtr)
{
if(sizeof(TEnum) == 4)
{
this->SetNullableUInt32Ptr(reinterpret_cast<CNullable<UInt32>*>(aEnumPtr));
}
else if (sizeof(TEnum) == 2)
{
this->SetNullableUInt16Ptr(reinterpret_cast<CNullable<UInt16>*>(aEnumPtr));
}
else if (sizeof(TEnum) == 1)
{
this->SetNullableUInt8Ptr(reinterpret_cast<CNullable<UInt8>*>(aEnumPtr));
}
else
{
this->FailEnumSize();
}
}
}
basic conditions
class CNullable follows the well known, basic nullable pattern implemented i.e. for c# in certain frameworks but could also be any template with one argument.
as the names imply, TEnum is used for different enum types. i.e. enum FooEnum { foo };
For different platforms/compilers it is true, that with for the same enum type it goes to different if branches: On Win32 all enums are compiled with a size of 4 bytes always. On my MCU it compiles to uint8, if the values of the enum field implies to do so.
1. Not my focus:
i'm not sure, if the c++ standard allows compliant compilers to generate enums with different sizes in respect of the required size but i think it is said, that it is compliant.
2. not my focus:
it is also obvious that a cleaner / more robust solution would generate explicit template instances for the function for ALL used enum types. however i might do this and hope the compiler/optimizer is smart/compliant enough not to generate extra code for all types.
3. Not my focus:
i know that reinterpret_cast can be evil but there is a reason the c++ standard defines it. so please stop downrating my questions just because you dont like it or dont understand it.
4. Not my focus:
i know there are certain websites, you can test code on different compilers.
5. would help too:
also if you have a better idea how to treat this coding issue you're welcome.
6. My focus:
i wanna focus this question on the issue, if the c++ standard [1] (or any other standard) defines rule(s), that the templates instances for intXX and uintXX (Where XX is the bit width and u indicates a unsigned version of the native integer) must forcefully compile to a code where a reinterpret_cast from CNullable<unsigned intXX> to CNullable<intXX> is guaranteed to run properly. it seems to be likely that a straight forward implementation of the tool chain may not cause problems in this case, but i got used to be carefull with such assumptions.
conclusion:
if one could give me the reference(s) to chapter inside the (c++) or other standard treading these issues (1 to 6) - that would be great.
thank you!
[1] Please understand the sad reality, that the platform i work on does even not have a ready compiler specification. so it is quite trial and error and i wanna understand the techniques behind to get a better feeling for it - because treading the issue deterministic seems not to be possible since the compiler reference does not give a clear statement what standard it supports: They stated an ETSI standard rather than an iso c++ standard and they didnt give enough info to find the documentation of the standard - no version number, no document number, no document name. when i search for the info given in the compiler documentation on the ETSI page i get > 24.000 results (!) XD
PS: Edit: I request the info:
a) Which standards / specifications ensure that this code runs properly?
b) Does anyone have a clean solution for an abstraction using different template instances for different enum types?
Ok think i i have a clean solution. It uses a wrapper pattern to hide the abstraction of concrete value types behind a virtual method.
I hope that is enough code to get the intention. I also put a very simple example of how i use it.
I guess in newer c++ version there are some stl elements which can replace the classes i wrote. But i need it for a very old c++ standard, which even isn't iso.
I really hope there are no errors since not all symbols are defined. but the essential stuff shall be shown in this example implementation.
// platform dependent UInt32 type.
typedef unsigned __int32 UInt32;
template<typename T>
class CNullable
{
public: bool HasValue;
public: T Value;
public: CNullable(): Value(), HasValue(false) {}
public: CNullable(const T& aValue): Value(aValue), HasValue(true) {}
public: template<typename T1>
CNullable<T1> To() const
{
return this->HasValue ? CNullable<T1>(static_cast<T1>(this->Value)) : CNullable<T1>();
}
CNullable<UInt32> ToU32n() const
{
return this->To<UInt32>();
}
};
// U32-Nullable type
typedef CNullable<UInt32> UInt32n;
// U32-Nullable argument type.
typedef const CNullable<UInt32>& UInt32na;
// Some kind of variant value that can store different types of values pointing into an (intended) statically allocated model
class CValue
{
// Report failure. Break debuger, raise exception, log error - whatever.
private: static void Fail(const char* aTextPtr);
// Sets the value in the (intended) statically allocated datamodel
// Simple example with a UInt32 as new value
public: void SetTargetValue(UInt32na rhs);
// Sets the value in the (intended) statically allocated datamodel
// May use a visitor pattern (GOF) for resolving assigned types, but thats not the topic here.
public: void SetTargetValue(const CValue& rhs);
// Ensures that object is not sealed an fails if so.
private: bool CheckNotSealed();
// Allows to change to sealed state to protect the object agains modification.
// protection for "as static as possible"-memory-design
public: void Seal();
// Base class for Wrappers
class CValueWrapper
{
public: virtual ~CValueWrapper() {}
// Converts the current value as an U32.
public: virtual UInt32n GetInterpretedU32n() { Fail("Data conversion not supported."); return UInt32n(); }
// converts the new value from an U32 and sets the value
public: virtual void SetInterpretedU32n(UInt32na aU32n) { Fail("Data conversion not supported."); }
};
// Wrappers Base class for any enum related type.
class CEnumWrapperBase : public CValueWrapper
{
public: virtual UInt32n GetU32n() const = 0;
public: virtual void SetU32n(UInt32na aU32n) const = 0;
public: virtual UInt32n GetInterpretedU32n() { return this->GetU32n(); }
public: virtual void SetInterpretedU32n(UInt32na aU32n) { this->SetU32n(aU32n); }
};
// Wrapper base class for values of type = Nullable<TEnums>
template<class TEnum> class CNullableEnumWrapper : public CEnumWrapperBase
{
private: CNullable<TEnum>* mNullableEnumPtr;
public: CNullableEnumWrapper(CNullable<TEnum>* aNullableEnumPtr)
:
mNullableEnumPtr(aNullableEnumPtr)
{
}
public: virtual UInt32n GetU32n() const
{
return this->mNullableEnumPtr ? this->mNullableEnumPtr->ToU32n() : UInt32n();
}
public: virtual void SetU32n(UInt32na aU32n) const
{
if (this->mNullableEnumPtr)
{
*this->mNullableEnumPtr = aU32n.To<TEnum>();
}
}
};
// Wrapper base class for values of type = Nullable<TEnums>
template<class TEnum> class CEnumWrapper : public CEnumWrapperBase
{
public: CEnumWrapper(TEnum* aEnumPtr)
:
mEnumPtr(aEnumPtr)
{
}
private: TEnum* mEnumPtr;
public: virtual UInt32n GetU32n() const
{
return this->mEnumPtr ? static_cast<UInt32>(*this->mEnumPtr) : UInt32n();
}
public: virtual void SetU32n(UInt32na aU32n) const
{
if (this->mEnumPtr
&& aU32n.HasValue)
{
*this->mEnumPtr = static_cast<TEnum>(aU32n.Value);
}
}
};
// Allows to lock instantian of wrapper objects.
// In my bare metal application all wrappers are created on application startup
// and stay allocated until the device is switched of (by disconnecting power)
// [ThreadStatic]
public: static bool InstanciateValueWrapperEnabled;
// Set pointer to enum value (intended to be allocated in a static model)
public: template<class TEnum> void SetEnumValuePtr(TEnum* aEnumPtr)
{
if (this->InstanciateValueWrapperEnabled)
{
if (this->CheckNotSealed())
{
this->SetValueWrapperPtr(new CEnumWrapper<TEnum>(aEnumPtr), true);
}
}
else
{
Fail("Invalid operation.");
}
}
// Set pointer to nullable<enum> value (intended to be allocated in a static model)
public: template<class TEnum> void SetNullableEnumValuePtr(CNullable<TEnum>* aEnumPtr)
{
if (this->InstanciateValueWrapperEnabled)
{
if (this->CheckNotSealed())
{
this->SetValueWrapperPtr(new CNullableEnumWrapper<TEnum>(aEnumPtr), true);
}
}
else
{
Fail("Invalid operation.");
}
}
// Sets the member var and data type to 'CValueWrapper' (may support some types natively without a wrapper object)
public: void SetValueWrapperPtr(CValueWrapper* aValueWrapperPtr, bool aOwning);
};
// Model Base Code
//////////////////////////////////////
/// Application specific code
enum FooEnum { FooEnum_Val1 };
// Reads data from StdIn, uart, or whatever.
UInt32 ReadU32();
// Process data, for example output calculated data to another hardware interface.
void Process(CValue** aValuePtrs);
// Simple example of how its being used.
// in real environment its likely to encapsulate a set of CValue objects
// in a ModelInstance-Object and build it by a ModelDefinition object parsing a model definiton language (mdl)
// or adapt generated code. etc. etc...
void main()
{
// Define the static model:
static FooEnum gFooEnum;
static CNullable<FooEnum> gNullableFooEnum;
// Define the values to access the static model
CValue aFooEnumVal;
CValue aNullableFooEnumVal;
// Begin of init:
CValue::InstanciateValueWrapperEnabled = true;
aFooEnumVal.SetEnumValuePtr(&gFooEnum);
aNullableFooEnumVal.SetNullableEnumValuePtr(&gNullableFooEnum);
CValue::InstanciateValueWrapperEnabled = false;
// End of init
// Create an array of values
const UInt32 aPropertyCount = 2;
CValue* aPropertyPtrs[aPropertyCount] =
{
&aFooEnumVal,
&aNullableFooEnumVal
};
for (UInt32 aIdx = 0; aIdx < aPropertyCount; ++aIdx)
{
aPropertyPtrs[aIdx]->Seal();
}
// Very simple and unsave data receiption loop.
while (true)
{
UInt32 aPropertyIdToSet = ReadU32(); // The property id to receive.
UInt32 aNewValHasValue = ReadU32(); // Wether the value is defined
UInt32 aNewValValue = ReadU32(); // The value
UInt32n aNewVal // Nullable for NewValue
= aNewValHasValue // if value is defined
? UInt32n(aNewValValue) // Create a nullable which has a value
: UInt32n() // Create a nullable which has no value
;
CValue* aValuePtr = aPropertyPtrs[aPropertyIdToSet]; // Get the value to receive.
aValuePtr->SetTargetValue(aNewVal); // Set the value to the static model
Process(aPropertyPtrs); // Process data newly received.
}
}

Accessing another object's member [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm a beginner to C++ and I was wondering if there was a good way to access a member of another object.
Currently I'm using this to access the members:
&_HeatSensor->IsOverheating == true;
&_LeftLegSensor->IsStalled == true;
/*... many more similar ones but different names*/
Where HeatSensor or LeftLegSensor is the name of the object and IsOverheating or IsStalled is a Boolean member in the object.
I want to create a new SensorOverLimit class, and create many objects(ex: Left Leg, MotorTemperature... etc.
To save time and reuse code, I want to be able to pass something that can reference the Boolean members that were created in the constructor and then save the location via reference or pointer as a member in the new SensorOverLimit object.
SensorOverLimit.cpp
SensorOverLimit::SensorOverLimit(bool* SensorAddress)
{
bool* Sensor = SensorAddress;
}
SensorOverLimit::Check()
{
if (SensorAddress == true)
{
somefunction();
}
}
main.cpp:
SensorOverLimit Overheating = new SensorOverLimit(bool* &_HeatSensor->IsOverheating);
SensorOverLimit DamagedLeg = new SensorOverLimit(bool* &_LeftLegSensor->IsStalled);
This doesn't work, does anyone have any ideas for how to get this to work?
Edit: Changed question, new answer...
SensorOverLimit.h:
class SensorOverLimit
{
bool* sensor;
public:
SensorOverLimit(bool* sensorAddress);
void check();
};
SensorOverLimit.cpp:
SensorOverLimit::SensorOverLimit(bool* sensorAddress)
: sensor(sensorAddress)
{
}
void SensorOverLimit::check()
{
if(*sensor)
{
somefunction();
}
}
Have a look at Remy's answer for references instead of pointers (bool& instead of bool*, and you can omit dereferencing (if(sensor))
main.cpp:
HeatSensor heatSensor;
LeftLegSensor leftLegSensor;
SensorOverLimit overHeating(&heatSensor.isOverheating);
SensorOverLimit leftLegDamaged(&leftLegSensor.isStalled);
int main(int, char*[])
{
// ...
return 0;
}
You might have noticed: I directly instantiated global variables. This is often more appropriate in embedded environments, at least easier to use.
Be careful with identifiers starting with an underscore - these are reserved in many cases (C++ standard, 2.10):
Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
Edit 2:
I'm coming up with a completely different design, inverting what you had so far:
class Sensor
{
public:
Sensor()
: isActive(false)
{ }
virtual ~Sensor()
{ }
void check()
{
if(getValue() != isActive)
{
isActive = !isActive;
if(isActive)
{
someFunction();
}
}
}
private:
bool isActive;
virtual bool getValue() = 0;
};
class HeatSensor : public Sensor
{
virtual bool getValue()
{
bool isActive = false;
// do what ever is necessary to detect overheat
// e. g. read from ADC and compare against threshold
return isActive;
}
};
class LegSensor : public Sensor
{
bool isSignal;
virtual bool getValue()
{
// do what ever is necessary to detect stalled leg
// e. g.: simply returning the value that has been set from
// within an interrupt handler
return isSignal;
}
};
Not really happy about the names of my members, you might find something better...
What is your intention of this design, however? Are you going to iterate over each city, checking the bool pointers? Seems a questionable design to me...
I suggest an alternative for you:
Each Sensor gets a SensorOverLimit* pointer, you might call it 'controller' or whatever seems appropriate to you. Then add functions to each Sensor class: oveheating(), stalling(), etc. Within these functions, you call a newly defined function of SensorOverLimit: disturb(int reason, Sensor* source). Instead of int, you could define an enum containing all possible reasons, such as Overheat, Stall, etc.
Could look like this:
class Sensor;
class SensorOverLimit
{
// appropriate members
public:
enum Disturbance
{
Overheat,
Stall,
};
SensorOverLimit() {}
void disturb(Disturbance reason, Sensor* source)
{
someFunction();
}
};
class Sensor
{
protected:
SensorOverLimit* controller;
public:
// ctor, getters, setters as needed
Sensor(SensorOverLimit* aController) : controller(aController) {}
};
class HeatSensor : public Sensor
{
public:
// ctor, getters, setters as needed
HeatSensor(SensorOverLimit* aController) : Sensor(aController) {}
void overheating()
{
if (controller)
controller->disturb(SensorOverLimit::Overheat, this);
}
};
class LegSensor : public Sensor
{
public:
// ctor, getters, setters as needed
LegSensor(SensorOverLimit* aController) : Sensor(aController) {}
void stalling()
{
if (controller)
controller->disturb(SensorOverLimit::Stall, this);
}
};
SensorOverLimit controller;
HeatSensor heatSensor(&controller);
LegSensor leftLegSensor(&controller);
int main(int, char*[])
{
// ...
heatSensor.overheating();
//...
leftLegSensor.stalling();
//...
return 0;
}
Advantage: You can associate many sensors to one and the same controller.
You can use a bool* pointer like this:
class SensorOverLimit
{
public:
bool* Sensor;
SensorOverLimit(bool* SensorAddress);
void Check();
};
...
SensorOverLimit::SensorOverLimit(bool* SensorAddress)
: Sensor(SensorAddress)
{
Check();
}
void SensorOverLimit::Check()
{
if (*Sensor)
{
somefunction();
}
}
SensorOverLimit *Overheating = new SensorOverLimit(&(_HeatSensor->IsOverheating));
SensorOverLimit *DamagedLeg = new SensorOverLimit(&(_LeftLegSensor->IsStalled));
...
Then you can do this:
_HeatSensor->IsOverheating = true;
...
Overheating->Check();
_LeftLegSensor->IsStalled = true;
...
DamagedLeg->Check();
With that said, it would be safer to use references instead of pointers:
class SensorOverLimit
{
public:
bool& Sensor;
SensorOverLimit(bool& SensorAddress);
void Check();
};
...
SensorOverLimit::SensorOverLimit(bool& SensorAddress)
: Sensor(SensorAddress)
{
Check();
}
void SensorOverLimit::Check()
{
if (Sensor)
{
somefunction();
}
}
SensorOverLimit *Overheating = new SensorOverLimit(_HeatSensor->IsOverheating);
SensorOverLimit *DamagedLeg = new SensorOverLimit(_LeftLegSensor->IsStalled);
...
_HeatSensor->IsOverheating = true;
...
Overheating->Check();
_LeftLegSensor->IsStalled = true;
...
DamagedLeg->Check();
Is there a particular reason why you're not using getters and setters in order to access the members of your objects?
If you're referencing to all your objects as pointers, you may want to reconsider that practice. This StackOverflow question gives some insight into common practice with C++ and pointers: Why should I use a pointer rather than the object itself?
I think the best answer to your question would actually be to familiarize yourself with the concept of pointers. This question as well the one I mentioned earlier give a good starting point - C++ Objects: When should I use pointer or reference. I think one of the best things to note is that if you are coming from a Java background, pointers and references are hidden in the code for you. Every object is a pointer and vice versa in Java. In C++, they are separate.
I think your desire to reuse code is commendable, but in this case, using pointers will probably cause unknown errors!
I'd recommend changing your constructor in the City class to actually work with the objects, not just their members (for instance, create a City with a person as your parameter, not whether the person is alive or dead). With a little more practice in object-oriented programming, you may find that it is much easier than your initial approach!

Class composition with public member objects

I am trying to figure out the best way to design my program features.
A major component of the program is a Camera class. This Camera object represents the program user interface to a real camera, which interfaces to a computer through a frame grabber card. The camera class can link to a frame grabber, start and stop acquisition, and also mutate/access many different camera properties. When I say many, I'm talking about over 250 unique commands. Each unique command is issued to the camera by sending a serial string through the framegrabber to the physical camera. Each command can be thought of as one of three types. An action, a query, and a value.
An action command is something that doesn't require an equals sign, for example "reset", "open", "close"
A query is something that you can get, but not set, that is usually associated with a value. For example "temperature=?", "sernum=?", "maxframerate=?" commands would cause the camera to send back information. These values cannot be mutated so "temperature=20" would result in an error.
A value is something you can get and set that is usually associated with a value. For example "framerate=30" and "framerate=?" are two unique commands, but I consider the base string "framerate" to be a value command type because it can be both mutated and accessed.
The 250 unique commands can be reduced to ~100 CameraActions, CameraQuerys, and CameraValues. Instead of having 250 methods in my Camera class, I had an idea to compose command objects instead of individual setters, getters, and actions. The command string can be provided in the constructor, or reset with a setter. Then I could compose a CameraCommands object that holds all of the available commands, and provide that as a public member to my Camera.
//CameraAction.h =============================================
class CameraAction {
public:
CameraAction(std::string commandString, SerialInterface* serialInterface);
void operator()() { _serialInterface->sendString(_commandString); }
private:
SerialInterface* _serialInterface;
std::string _commandString;
};
//CameraValue.h =====================================================
class CameraValue {
public:
CameraValue(std::string commandString, double min, double max, SerialInterface* serialInterface);
void set(double value)
{
if(value > _maxValue) { throw std::runtime_error("value too high"); }
if(value < _minValue) { throw std::runtime_error("value too low"); }
std::string valueString = std::to_string(value);
_serialInterface->sendString(_commandString + "=" + valueString);
}
double get()
{
std::string valueString = _serialInterface->sendString(_commandString + "=?");
return atof(valueString.c_str());
}
private:
SerialInterface* _serialInterface;
std::string _commandString;
double _minValue;
double _maxValue;
};
//CameraCommands.h ===================================================
class CameraCommands {
public:
CameraCommands();
CameraAction reset;
CameraQuery temperature;
CameraValue framerate;
CameraValue sensitivity;
//... >100 more of these guys
};
//Camera.h ===========================================================
class Camera {
public:
Camera();
CameraCommands cmd;
void startAcquisition();
void stopAcquisition();
void setDataBuffer(void* buffer);
void setOtherThing(int thing);
};
so that the user could do something like:
Camera myCamera;
myCamera.cmd.reset();
myCamera.cmd.framerate.set(30);
myCamera.cmd.sensitivity.set(95);
double temperature = myCamera.cmd.temperature.get();
myCamera.startAcquisition();
etc...
The main problem here is that I'm exposing public member variables, which is supposed to be a massive no-no. Is my current object design logical, or should I simply implement 250 setters and getters and 100 more setters and getters to mutate the minimum and maximum settable values.
This seems kludgey to me because there are also many setters/getters associated with the Camera object that are unrelated to the user commands. It's nice for the user interface to provide the scope of the method (cmd) for the user to know whether something is being mutated physically in the camera, or just being mutated in the programmatic object (other methods). Is there any better way to design my program?
You've basically described an interesting hierarchy:
Command -> Query -> Value.
A Command holds the string that is the text of the command;
It can also offer a protected Send() method for its children to call.
A Query also holds a (protected) int variable (or whatever) that you can get() and/or operator int() immediately, or query() from the camera;
A Value adds the set() and/or operator =(int) command to Query.
The constructor (in particular) of Value can have min and max as you describe.
The Camera object can then have a number of public members:
class Camera {
private: // Classes that no-one else can have!
class Command; friend Command;
#include "Camera.Command.inc"
class Query; friend Query;
#include "Camera.Query.inc"
class Value; friend Value;
#include "Camera.Value.inc"
public: // Variables using above classes
Command reset;
Command open; // Maybe make this one private, for friends?
Command close; // Ditto?
Query temperature;
Query sernum;
Query maxFrameRate;
Value frameRate;
private: // Variables
SerialPort port; // Allow Command and co. access to this
}; // Camera
By organising it like this, then:
The user of the variables can't make impossible requests - there is no method to do so;
The query() and set() methods hide the mechanism to interface with the physical camera.
You'll note I've added #include "Camera.XXX.inc" in the middle of the Camera class. Note:
It doesn't clutter the Camera class with the definitions of those sub-Classes - but the C++ compiler needs them before you can use them, so you need to have them there. And if you want to know what they do, just open the file!
I gave them the .inc extension since they're "included" in the .h file: they don't stand alone as their own header file.
You can use one or more structs to group "settings", and then expose a method to set them:
typedef struct settings{
int setting1;
int setting2;
}MySettings;
class Myclass{
private :
int setting1;
int setting2;
public Myclass(MySettigs *settings)
{
if(null != settings){
setting1=settings->setting1;
setting2=settings->setting2;
}
}
public void ChangeSettings (MySettings *setting){
if(null != settings)
{
setting1=settings->setting1;
setting2=settings->setting2;
}
}
public void TakeSettings (MySettigs *settings){
[copy local variables into the passed struct]
}
I strongly advise to be careful when changing settings while the object is "operational".You can fall in an undefined state where settings are being changed while another thread is using them.
In your mentioned design I don't think exposing public members through composition is a big no-no.
When exposing public members, the big no-no is unsafe access to your class internals.
An example would be allowing public access to CameraValue::_maxValue. A user could change that value to anything, causing all sorts of undefined behaviour.
Were it up to me to design this I wouldn't have a CameraCommands member, as from the looks of it it doesn't add anything other then a level of indirection.
I would either add all the CameraAction and CameraValue members as part of the camera class, or inherit them.
Something like this:
Merging CameraCommands into Camera:
class Camera
{
public:
Camera();
CameraAction reset;
CameraQuery temperature;
CameraValue framerate;
CameraValue sensitivity;
//... >100 more of these guys
void startAcquisition();
void stopAcquisition();
void setDataBuffer(void* buffer);
void setOtherThing(int thing);
};
Inheriting CameraCommands into Camera:
class Camera : public CameraCommands
{
public:
Camera();
void startAcquisition();
void stopAcquisition();
void setDataBuffer(void* buffer);
void setOtherThing(int thing);
};
You can even provide some operators for CameraValue etc so that you can set a value through assignment (operator=), and get a value through either implicit conversion (operator T) or dereferencing (operator*):
template<typename T>
class CameraValue
{
public
CameraValue(SerialInterface*, std::string cmd);
CameraValue& operator=(const T& val)
{
_val = val;
std::string val_str = std::to_string(_val);
_ser_ifc->sendString(_cmd + "=" + val_str);
}
const T& get() const
{
return _val;
}
// implicit access to _val
operator const T&() const
{
return _val;
}
// dereference operator to access _val
const T& operator*() const
{
return _val;
}
private:
T _val;
SerialInterface* _ser_ifc;
std::string _cmd;
};
Then use CameraValue in your class as follows:
using CameraFramerate = CameraValue<int>;
CameraFramerate framerate;
The above techniques offer (IMO) a more composable use of Camera, such as the following:
Camera camera;
// setting values
camera.framerate = 30;
camera.sensitivity = 95;
// getting values
int framerate = camera.framerate; // uses operator T&()
int framerate = *camera.framerate; // uses operator*()
The key point here is that Camera::framerate etc don't allow any access that could change your camera class' internal state in an undefined and/or unsafe manner.

Updating data members of different derived classes of the same base class within a vector

I am writing a 3D gridded model in C++ which has different cell types, all stored within a vector that is in a Grid class. I have defined a base GridCell class and I also have two derived classes GridCell1 and GridCell2.
Now in setting up the model, I read in a text file that tells me how to fill my gridCell vector (std::vector<gridCell*> gridCellVector) in the Grid class; meaning it tells me what types of derived cells to push_back into my gridCellVector.
Then I read in another input file that contains initial state variable information for each GridCell in my Grid, in the order laid out by the 1st input file.
Each derived class (GridCell1 and GridCell2) has some state variables (private data members) that the other doesn't. How can I (or is it possible to) access and update/initialize/set the derived class' data members as I read in the second input file?
I've tried a couple different things and seem only able to return my get/set functions defined in the GridCell base class. I can't figure out how to access the functions in the derived classes when working with each derived GridCell as I step through the vector.
Edit: I am surprised people haven't mentioned downcasting, other than saying not to use dynamic_cast. I always know the type of GridCell I am updating because I keep track of what has been loaded into the vector when reading in the first input file. Since i am always certain of the type of GridCell, isn't dynamic_cast safe?
Double Edit:. Because I pass the GridCell objects to other functions that need to reference the data members and functions specific to the appropriate GridCell instance of the passed object, I'm realizing the design (of many parts) of my model does not currently pass muster. So, for now, I'm giving up on the idea of having to ride the GridCelltypes at all and will just create one huge GridCell class that fits all my needs. This way I can fill, and then access, whatever data members and functions I need later on down the line.
If you're sure you want to use a two-step process, I suggest you give GridCell a pure virtual init method:
virtual void init(istream &) = 0;
then implement it in each derived class. Its purpose is to read data from the file and initialize the initial state variables.
Single pass
As others have said, it may be best to read both files at once and do the derived class specific initialization at the same time as creating the derived classes:
std::unique_ptr<GridCell> createGridCell1(std::istream& init) {
auto cell = std::make_unique<GridCell1>();
int value;
init >> value;
cell->setGridCell1State(value);
return cell;
}
std::unique_ptr<GridCell> createGridCell2(std::istream& init) {
// similarly to CreateGridCell1()...
}
std::vector<GridCell::Ptr> createCells(std::istream& types, std::istream& init) {
std::vector<GridCell::Ptr> cells;
std::string type;
while (types >> type) {
if (type == "GridCell1")
cells.push_back(createGridCell1(init));
else
cells.push_back(createGridCell2(init));
}
return cells;
}
int main() {
auto types = std::istringstream("GridCell1 GridCell2 GridCell1 GridCell1");
auto init = std::istringstream("1 2.4 2 3");
auto cells = createCells(types, init);
for (auto& cell : cells)
cell->put();
}
Live demo.
Two pass with Visitor
If you must do the initialization in a second pass you could use the Visitor pattern. You have some sort of GridCellVisitor that knows how to visit all the different kinds of grid cells:
class GridCellVisitor {
protected:
~GridCellVisitor() = default;
public:
virtual void visit(GridCell1& cell) = 0;
virtual void visit(GridCell2& cell) = 0;
};
and your grid cells know how to accept a GridCellVisitor:
class GridCell1 : public GridCell {
int state = 0;
public:
void setGridCell1State(int value) { state = value; }
void accept(GridCellVisitor& visitor) override { visitor.visit(*this); }
};
class GridCell2 : public GridCell {
double state = 0.0;
public:
void setGridCell2State(double value) { state = value; }
void accept(GridCellVisitor& visitor) override { visitor.visit(*this); }
};
This way you can separate the responsibility of initializing the grid cells with an input stream from the grid cells themselves and avoid having to do fragile downcasts on the grid cells:
class GridCellStreamInitializer : public GridCellVisitor {
std::istream* in;
public:
GridCellStreamInitializer(std::istream& in) : in(&in){}
void visit(GridCell1& cell) override {
int value;
*in >> value;
cell.setGridCell1State(value);
}
void visit(GridCell2& cell) override {
double value;
*in >> value;
cell.setGridCell2State(value);
}
};
int main() {
auto in = std::istringstream("GridCell1 GridCell2 GridCell1 GridCell1");
auto cells = createCells(in);
auto init = std::istringstream("1 2.4 2 3");
auto streamInitializer = GridCellStreamInitializer(init);
for (auto& cell : cells)
cell->accept(streamInitializer);
}
Live demo.
The downside is GridCellVisitor must be aware of all different kinds of grid cells so if you add a new type of grid cell you have to update the visitor. But as I understand it your code that reads the initialization file must be aware of all the different kinds of grid cells anyway.
Your vector<gridCell*> knows only the base class of its elements and can hence only call gridCell functions.
I understand that your approach, is to first fill the vector with pointer to cells of the correct derived type, and never the base type. Then for each cell, you read class dependent data.
The easiest way, if you don't want to change approach
The cleanest way would be to define a virtual load function in the base cell:
class gridCell {
...
virtual bool load (ifstream &ifs) {
// load the common data of all gridCells and derivates
return ifs.good();
}
};
The virtual function would be overriden by teh derived cells:
class gridCell1 : public gridCell {
...
bool load (ifstream &ifs) override {
if (gridCell::load(ifs)) { // first load the common part
// load the derivate specific data
}
return ifs.good();
}
};
Finally, you can write your container loading function:
class Grid {
...
bool load (ifstream &ifs) {
for (auto x:gridCellVector)
if (!x->load(ifs))
break; // error ? premature end of file ? ...
}
};
The cleanest way ?
Your problem looks very much like a serialisation problem. You load grids, may be you write grids as well ? If you control the file format, and perform the creation and loading of the cells in a single pass, then you don't need to reinvent the wheel and could opt for a serialisation library, like boost::serialization.

Converting objects of base class to derived class

I asked a couple days ago some clarifications on inheritance, a concept I am still trying to understand. Here is the follow up question, since I am still facing problems.
In my project I have 2 types of objects, Hand and Face, both inheriting from the base class BodyPart. BodyPart is something like this:
class BodyPart
{
public:
typedef boost::shared_ptr<BodyPart> BodyPartPtr;
BodyPart();
virtual ~BodyPart();
private:
int commonMember1;
double commonMember2;
public:
int commonMethod1();
int CommonMethod2();
}
while Hand is something like this:
class Hand : public BodyPart
{
public:
Hand();
~Hand();
private:
int numFingers;
double otherVar;
public:
int getNumFingers();
void printInfo();
}
I also have a vector of BodyPart elements
std::vector<BodyPart::BodyPartPtr> cBodyParts;
composed of Hand or Head objects. In the previous question I was told that this approach makes sense, I just had to cast from the base class to the derived using boost static_pointer_cast
Now, the problem now is that for some of the objects in the vector I don't know whether they are Hand or Head, so at some point in my code I can have in cBodyParts some Hand elements, some Head elements as well as some BodyPart elements. After some further analysis I am able to correctly classify the latter as either Hand or Head and modify accordingly the elements in the vector, but I have no idea on how to make it. Shall I just delete the case class element and create a derived one with the same property? Shall I just avoid inheritance in case like this?
Thanks in advance for the help
EDIT: I have augmented the examples to make them clearer.
Relaying on casts is usually a sign of a bad design. Casts have their place, but this does not look to be it.
You need to ask yourself what do you want to do with the objects stored in cBodyParts. For sure, you will be doing different things with a Hand or with a Head, but you can probably abstract them somehow: this is what virtual functions do. So, in addition to what you have already written for your classes, you would just need an additional virtual function in them:
class BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() = 0; // Pure virtual: each body part must say how to process itself
virtual void CalibrateJoints() {} // Override it only if the body part includes joints
}
class Head : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Head
}
// Since a Head has no joints, we don't override the CalibrateJoints() method
}
class Hand : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Hand
}
virtual void CalibrateJoints() {
// Code to calibrate the knuckles in the hand
}
}
And then you no longer need any casts. For instance:
for (BodyPart::BodyPartPtr part : cBodyParts) {
part->InitialisePart();
part->CalibrateJoints(); // This will do nothing for Heads
}
As you can see, no casts at all and everything will work fine. This scheme is extensible; if you later decide that you need additional classes inheriting from BodyPart, just write them and your old code will work correctly:
class Torso : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Torso
}
// The Torso has no joints, so no override here for CalibrateJoints()
// Add everything else the class needs
}
class Leg : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Leg
}
virtual void CalibrateJoints() {
// Code to calibrate the knee
}
// Add everything else the class needs
}
Now you don't need to change the code you wrote previously: the for loop above will work correctly with and Torso or Leg it finds with no need for an update.
The hip bone's connected to the thigh bone...
I take it you have some composite of all the body parts, maybe a Body class.
What do you want the body to do?
Render itself
Serialise
Ouput its volume, or bounding box, or some other metric
Re-orient itself in response to input
Respond to an inverse-kinematic physical model
The list could probably go on. If you know exactly what you want the Body to do you can put that function in the BodyPart base class, and have Body iterate over the composite hierarchical structure of all the connected body parts, calling render, for example.
An alternative is to use a Visitor, which is effectively a way of dynamically adding methods to a static inheritance hierarchy.
As Kerrek SB pointed out this is not feasible at all, but for the sake of answering the actual question, dynamic_cast is what you are looking for.
Use virtual functions, they will simplify a lot your problem.
Else, you can add some methods to distinguish between different types. However, do it only if you cannot do it another way, ie if you cannot do it via virtual functions.
Example 1:
// in BodyPart; to be reimplemented in derived classes
virtual bool isHand() const { return false; }
virtual bool isHead() const { return false; }
// in Hand (similar to what will be in Head)
bool isHand() const { return true; }
// How to use:
BodyPart::pointer ptr = humanBodyVector[42]; // one item from the array
if(ptr->isHand())
processHand(/*cast to hand*/)
else if(ptr->isHead())
// ...
Example 2: let the derived classes handle the cast
// in BodyPart; to be reimplemented in derived classes
virtual Hand* toHand() const { return 0; }
virtual Head* toHead() const { return 0; }
// in Hand (similar to what will be in Head)
Hand* toHand() const { return this; }