How to change a behavior for all instances of a class in a header only class - c++

For a class, which is only defined in a header, I need a special behavior of one method for all instance of the class. It should be depending on a default value, which can be changed any time during runtime. As I do not want a factory class nor a central management class I came up with that idea:
class MyClass
{
public:
void DoAnything() // Methode which should be act depending on default set.
{
// Do some stuff
if(getDefaultBehaviour())
{
// Do it this way...
}
else
{
// Do it that way...
}
}
static bool getDefaultBehaviour(bool bSetIt=false,bool bDefaultValue=false)
{
static bool bDefault=false;
if(bSetIt)
bDefault=bDefaultValue;
return bDefault;
}
};
It works, but it looks a little awkward. I wonder if there is a better way following the same intention.
In the case where I want to use it the software already created instances of that class during startup and delivered them to different parts of the code. Eventually the program gets the information how to treat the instances (for e.g. how or where to make themselves persistent). This decision should not only affect new created instances, it should affect the instances already created.

I'd advise to use a simple method to simulate a static data member, so the usage becomes more natural:
class MyClass
{
public:
// get a reference (!) to a static variable
static bool& DefaultBehaviour()
{
static bool b = false;
return b;
}
void DoAnything() // Methode which should be act depending on default set.
{
// Do some stuff
if(DefaultBehaviour())
{
// Do it this way...
}
else
{
// Do it that way...
}
}
};
where the user can change the default at any time with
MyClass::DefaultBehaviour() = true;

My thanks to Daniel Frey with his answer which I already marked as the best. I wanted to add my final solution which is based on the answer from Frey. The class is used by some c++ beginners. As I told them to use always getter and setter methods, the way described by Frey looks very complex to beginners ("uuuh, I can give a function a value?!?!"). So I wrote the class like followed:
class MyClass
{
public:
// get a reference (!) to a static variable
static bool& getDefaultBehaviour()
{
static bool b = false;
return b;
}
static void setDefaultBehaviour(bool value)
{
getDefaultBehaviour()=value;
}
void DoAnything() // Methode which should be act depending on default set.
{
// Do some stuff
if(getDefaultBehaviour())
{
// Do it this way...
}
else
{
// Do it that way...
}
}
};
for the user, I looks now like a usual getter and setter.

Related

C++ can't access field from inherited class

Hello guys a have a problem, that i can't access field tablica[i]->help, in generuj function, its saying that this field is not existing in class Task.
How can i achieve it ?
class Task
{
protected:
string contents;
int id_pyt;
int nr_pyt;
};
class Task4Answ : public Task
{
private:
int help;
public:
Task4Answ(string contents1, int id,int nr,int help1)
{
contents=contents1;
id_pyt=id;
nr_pyt=nr;
help=help1;
}
};
class TaskCollection
{
protected:
Task *collection[60];
public:
friend class Generator;
TaskCollection()
{
collection[0] = new Task4Answ("Ile jest por roku w Polsce? \na) 1 \nb) 2 \nc) 3 \nd) 4",1,0);
collection[1] = new Task4Answ("Kto wygral tegoroczny Roland Garros? \na) Federer \nb) Djokovic \nc) Nadal \nd) Thiem",1,1);
class Generator
{
protected:
Task *tablica[10];
TaskCollection T1;
public:
Generator(){}
void Generuj()
{
if(T1.collection[x]->id_pyt==1)
{
tablica[i]=new Task4Answ("0",0,0);
tablica[i]->contents=T1.collection[x]->contents;
tablica[i]->id_pyt=T1.collection[x]->id_pyt;
tablica[i]->nr_pyt=T1.collection[x]->nr_pyt;
tablica[i]->help=T1.collection[x]->help; //here is the problem
}
}
}
Or maybe there is some other solution of the project im doing now.
Thanks for any help.
The problem is in this line:
tablica[i]=new Task4Answ("0",0,0);
Although you have called the Task4Answ constructor, you are also assigning the memory address returned by new to a Task pointer. Effectively, you have casted the Task4Answ pointer to a Task pointer. On the lines that follow, C++ only sees tablica[i] as a reference to a Task pointer. You need to change:
protected:
Task *tablica[10];
TaskCollection T1;
...to this:
protected:
Task4Answ *tablica[10]; // Task was changed to Task4Answ
TaskCollection T1;
That should allow C++ to see tablica as an array of Task4Answ pointers instead of Task pointers.
Edit: it looks like help is also private. You will have to change help to public or add TaskCollection::TaskCollection() as a friend. Otherwise, C++ will not let you get or set help.
Edit: the OP added that tablica[i] might contain instances of other classes that inherit from Task. In that case, you could do something like this:
void Generuj()
{
if(T1.collection[x]->id_pyt==1)
{
Task4Answ* newTask = new Task4Answ("0",0,0);
newTask->contents=T1.collection[x]->contents;
newTask->id_pyt=T1.collection[x]->id_pyt;
newTask->nr_pyt=T1.collection[x]->nr_pyt;
newTask->help=T1.collection[x]->help; // You will still have to change this from being private.
tablica[i] = newTask;
}
}
}
Later on, in order to access help, you will need to implement some sort of way of checking whether tablica[i] is a Task4Answ and not an instance of some other class that inherits from Task, perhaps by implementing a method in Task named IsTask4Answ that returns false in Task but is overridden to return True in Task4Answ. You can then cast the pointer back to Task4Answ with something like the static_cast operator. In other words:
// Add these functions to the class definitions:
virtual bool Task::IsTask4Answ() const {
return false;
}
bool Task4Answ::IsTask4Answ() const override {
return true;
}
// Later, you can do this:
if(tablica[i].IsTask4Answ()){
Task4Answ* t = static_cast<Task4Answ*>(tablica[i]);
t->help; // Again, you'll have to change this from being private.
}
Although I suggest figuring out a different data structure where you do not need to do any casting, this will allow you to access help.
Do note the virtual keyword in the first function above; it allows the function to be dynamically bound, which means that the code will check whether to call Task::IsTask4Answ() or Task4Answ::IsTask4Answ() at runtime instead of at compile time.

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!

avoiding if statements on a static boolean for logic decision making

I have a class whose member itemType is only set once and never modified but it is used in many if-statements to decide which function to call.
Since itemType is only set once is there way to avoid the if statements else where in the class. This will simplify and clean the code and as a bonus will also save the overhead of if checks.
I was thinking about function a pointer taht I can initiatlize in the constructor based on the itemType value.
Is there any alternate and a better way of doing that?
Please note the original class and code base is large and I cant go around creating child classes based on itemtype.
enum ItemTypes
{
ItemTypeA,
ItemTypeB,
};
class ItemProcessing
{
public:
//This function is called hundreds of times
void ProcessOrder(Order* order)
{
//This member itemType is set only once in the constructor and never modified again
//Is there a way to not check it all the time??
if (itemtype == ItemTypes::ItemTypeA )
{
ProcessTypeA(order)
}
else if (itemtype == ItemTypes::ItemTypeB )
{
ProcessTypeB(order)
}
}
ItemProcessing(ItemTypes itype)
{
itemtype = itype; //can I do something here like setting a function pointer so I dont have to check this property in ProcessOrder() and call the relevant function directly.
}
private:
ItemTypes itemtype;
void ProcessTypeA(Order*);
void ProcessTypeB(Order*);
};
Use an array of function pointers, indexed by itemtype, like this:
typedef void(*ProcessType_func_t)(Order *);
ProcessType_func_t processType_f[] = {
ProcessTypeA,
ProcessTypeB
};
Then you can do:
void ProcessOrder(Order *order) {
ProcessType_f[itemtype](order);
}
If you have lots of different functions that need to be dispatched like this, you can use a structure.
struct {
ProcessType_func_t processType_f,
OtherType_func_t otherType_f,
...
} dispatchTable[] = {
{ ProcessTypeA, OtherTypeA, ... },
{ ProcessTypeB, OtherTypeB, ... }
};
Then you would use it as:
dispatchTable[itemtype].processType_f(order);
Finally, you could do the fully object-oriented method, by defining new classes:
class Processor { // abstract base class
public:
virtual void Process(Order *order) = 0;
};
class ProcessorA {
public:
void Process(Order *order) {
ProcessTypeA(order);
}
}
class ProcessorB {
public:
void Process(Order *order) {
ProcessTypeB(order);
}
}
Then you can have a member variable
Processor *processor;
and you initialize it when you set itemtype
ItemProcessing(ItemTypes itype)
{
itemtype = itype;
if (itemtype == ItemTypeA) {
processor = new ProcessorA;
} else {
processor = new ProcessorB;
}
}
Then you would use it as:
processor->Process(order);
This is easily expanded to support more functions that need to dispatch on itemtype -- they all become methods in the classes.
I hope I got the syntax right, I don't actually do much C++ OO programming myself.
You can consider to use either a couple of pointers to member methods or the state pattern.
The former solution has probably higher performance, while the latter is more elegant and flexible (at least from my point of view).
For further details on the state pattern, see here. This pattern fits well with your problem, even though you have to refactor a bit your classes.
I guess the first suggestion is indeed quite clear and does not require further details.
In c++ pointer to function should be mimic with virtual function and inheritance. (Polymorphism)
Define a virtual class including a pure virtual methods
processOrder ( Order* ordre);
And define subclass for each value of your enum.
You can use abstract factory pattern to creat those object or either if needed.
I can write the code if wish.

Static Virtual Functions

Okay, so I know that static virtual functions don't exist for several reasons. I do believe, however, I have found a situation in which something mimicking them may be useful. As part of a group project for a class we must design a scripting core for a game engine. In order to keep things decoupled we want a class to be able to register its metatables (functions, members, etc) with the LuaState. Also, I could be way off here as this is my first time trying to implement anything of the sort.
So, in order to keep things generic we have an IScriptStateManager interface that contains pure virtual functions to register objects with the scripting languages global state, perform init and shutdown features, and has a couple other functions for DoFile and DoString. Then we have a LuaStateManager class that implements the functionality of this interface.
Now, in order to allow most game objects to be created in script without knowing about them ahead of time we also created an IScriptObject interface. If you want an object to be represented by the scripting system it should implement this interface. This interface includes a method that contains a method called register that derived classes can implement and will set up there metatables. So everything looks like this:
bool LuaStateManager::Register(IScriptObject* obj)
{
if (obj has not already been registered with global state)
{
obj->Register();
return true;
}
return false;
}
I'm sure you can see the problem. First and foremost we need and actual instantiation to register an object. Because of this we may be calling this function multiple times for a particular type of object, only to have it return true the first time and false every other time. While the overhead of this is minimal, it's a dead giveaway that something is wrong with the design.
So the issue arises. In this particular case we need the functionality of both a static method and a virtual method. Granted we could simply manually add static methods to each class and then call those once, but this couples objects to the scripting system. Any tips or help would be most welcome. Thanks
Provide access to the functionality of IScriptStateManager through a set of functions in an API class or a namespace.
ScriptStateManagerAPI.h:
namespace ScriptStateManagerAPI
{
// Function to register the active ScriptStateManager.
void setActiveScriptStateManager(IScriptStateManager* scriptStateManager);
// Function to register a ScriptObject.
bool registerScriptObject(IScriptObject* obj);
}
IScriptStateManager.h:
class IScriptStateManager
{
virtual bool registerScriptObject(IScriptObject* obj) = 0;
};
ScriptStateManagerAPI.cpp:
#include <IScriptStateManager.h>
namespace ScriptStateManagerAPI
{
static IScriptStateManager* activeScriptStateManager = nullptr;
void setActiveScripStatetManager(IScriptStateManager* scriptStateManager)
{
activeScriptStateManager = scriptStateManager;
}
bool registerScriptObject(IScriptObject* obj)
{
if ( activeScriptStateManager )
{
return activeScriptStateManager->registerScriptObject(obj);
}
else
{
// Deal with lack of an active IScriptStateManager.
return false;
}
}
}
LuaScriptManager.h:
#include <IScriptStateManager.h>
class LuaScriptManager : public IScriptStateManager
{
virtual bool registerScriptObject(IScriptObject* obj);
};
LuaScriptManager.cpp:
namespace
{
// Helper class in anonymous namespace to register a LuaScriptManager as
// the active IScriptStateManager at start up time.
struct Initializer
{
Initializer();
};
};
// Construct an Initializer at start up time.
static Initializer initializer;
Initializer::Initializer()
{
// Register a LuaScriptManager as the acive ScriptStateManager.
ScriptStateAPI::setActiveScriptStateManager(new LuaScriptManager());
}
bool LuaScriptManager::registerScriptObject(IScriptObject* obj)
{
if (obj has not already been registered with global state)
{
obj->Register();
return true;
}
return false;
}
You can use another ScriptStateManager in your application. Then you have to choose whether you can have only one ScriptStateManager at a time or not. If your application needs more than one ScriptStateManager at a time, you can change the static data as well as the interface in ScriptStateManagerAPI
ScriptStateManagerAPI.h:
namespace ScriptStateManagerAPI
{
// Function to register an active ScriptStateManager.
void registerActiveScriptStateManager(IScriptStateManager* scriptStateManager);
// Function to register a ScriptObject.
bool registerScriptObject(IScriptObject* obj);
}
ScriptStateManagerAPI.cpp:
#include <IScriptStateManager.h>
namespace ScriptStateManagerAPI
{
static std::set<IScriptStateManager*> activeScriptStateManagers;
void registerActiveScripStatetManager(IScriptStateManager* scriptStateManager)
{
activeScriptStateManagers.insert(scriptStateManager);
}
bool registerScriptObject(IScriptObject* obj)
{
// Figure out how to manage the return the values of each
// activeScriptManager.
for ( auto activeScriptManager, activeScriptStateManagers)
{
activeScriptManager->registerScriptObject(obj);
}
return true; //????
}
}

Separate static variable inside class member function among instances

MyClass::Foo()
{
static bool isFirst = true;
if (isFirst)
do something;
isFirst = false;
}
MyClass::Bar()
{
static bool isFirst = true;
if (isFirst)
do something;
isFirst = false;
}
I have used the above structure and it worked well so far when I worked with only one instance of the class.
The problem is all instances of MyClass seem to share the static variable.
How can I make the variable not-shared by different instances(but shared among same instance)?
Do I need to maintain a separate data structure to store instances somewhere?
Or could this be done with clever use of c++ syntax?
edit
I forgot to mention I have such variables in many functions.
Added MyClass::Bar() up there.
I hope there's a way without defining isFirstForFoo, isFirstForBar, and so on as class member variables, because there are so many.
My actual code looks like this
BookInfoVector_t DBProcess_GET_BOOK::SelectBookList()
{
const char* query = "some query statement";
static nsl::SQLitePreparedStatement preparedStatement = nsl::SQLitePreparedStatement(static_cast<nsl::SQLiteConnection*>(mDBConnection), query);
static bool isFirst = true;
_InitializeDBProcess(&preparedStatement, isFirst);
...
}
I do some initialization on preparedStatement on first run of code, and as you can imagine, I have to define isFirst for all queries I use.
The problem is all instances of MyClass seem to share the static variable.
That is exactly what a static variable is.
How can I make the variable not-shared by different instances(but shared among same instance)?
You need to make isFirst a (non-static) member of MyClass. And rename it, following your edit:
class MyClass
{
public:
MyClass();
void Foo();
void Bar();
private:
bool should_foo;
bool should_bar;
};
MyClass::MyClass()
:should_foo(true)
,should_bar(true)
{
}
void MyClass::Foo()
{
if (should_foo)
{
// do something;
should_foo = false;
}
}
void MyClass::Bar()
{
if (should_bar)
{
// do something;
should_bar = false;
}
}
If you really "have such variables in many functions", then I recommend you rethink the design of MyClass. I can't tell you how, given how vague and generic your example is but you're almost certainly violating the Single Responsibility Principle.
In your MyClass.h file:
class MyClass {
public:
MyClass();
void Foo();
private:
bool isFirst;
}
In your constructor:
MyClass::MyClass() {
isFirst = true;
}
In your method:
void MyClass::Foo()
{
if (isFirst)
do something;
isFirst = false;
}
You may want to rename isFirst now to something like mIsFirst or isFirst_ or whatever your style guide recommends for member variables, since you have now made it an instance member.
You may also wish to use an initializer list in the constructor, instead of doing it in the body of constructor.
The above left as an exercise for the reader.
Use an instance variable in the class. The various member functions of a single class are expected to be tightly coupled, and not stomp on each other's data.