I sincerely hope that people on here don't mind these sorts of questions.
After having searched plenty of times, perhaps with the wrong search terms - nevertheless - I do not seem to be able to find ANYTHING on this.
Yes, I have looked through cplusplus' documentation, yet I still could not find out the answer.
My question is simple, how do I make it so that a function can only be called via another function?
Here's an example
class someclas{
public:
void screen():
void setsomevariable (int somevariable){}
}clas;
And when I call the function, setsomevariable(), it should only be able to be used after having called the screen function. As such:
clas.screen().setsomevariable(..);
Again, how do I make this function a member of screen() alone?
This does match your requirements, but doesn't necessarily meet your needs. Would like to help more but you're stubbornly refusing to give details...
class Screen {
public:
void setsomevariable (int somevariable) {}
};
class someclas {
Screen s;
public:
Screen& screen() { return s; }
} clas;
A member function belongs to a class. You can't make a function a member of another.
You could keep a boolean in your class, and throw an exception if screen wasnt called before. But it's an ugly solution..
class someclas{
public:
someclas & screen() { // returns a reference to your class to enable the clas.screen().setsomevariable() syntax
screenCalled = true;
return *this;
}
void setsomevariable (int somevariable){
if (!screenCalled) {
throw std::exception();
}
// some code
screenCalled = false;
}
bool screenCalled;
}clas;
Related
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.
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.
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.
I am making a class which inherits off another and must return the value of a function in the base class... It is confusing so I will let the code speak for itself...
class ParentClass {
public:
virtual bool getMyVal();
};
bool ParentClass::getMyVal() {
return true; // in my program there is a bit more to it
}
class ChildClass : public ParentClass {
public:
bool getMyVal();
};
bool ChildClass::getMyVal() {
CalculateMassOfSun();
return parent::getMyVal(); // Please make sure you read below...
}
So this is just an example of what I want to do, not the actual code. As you can see, in ChildClass::getMyVal(), is basically needs to do some pre-computation then run the same function in the parent class and return its value. I know that it is a virtual function in the parent, and that I have not gone about invoking the function in the parent the right way - it is how it is done in PHP and the only way I can think of that makes sense to me and hopefully others at the moment.
So how would I go about doing this? At the moment, I have found something along the lines of:
bool ChildClass::getMyVal() : /*ParentClass::*/getMyVal() { ... }
however it does not return the value here.
Thanks in advance for your responses.
To invoke the base definition of getMyVal just prefix the call with the base type name
return ParentClass::getMyVal();
If you want to call ParentClass version of getMyVal() then do this:
bool ChildClass::getMyVal() {
CalculateMassOfSun();
return ParentClass::getMyVal(); // this will call parent version
}
I have a CognitiveEntity class, defined this way:
class CognitiveEntity : public Object
{
public:
CognitiveEntity (FuzzyCognitiveMap fcm, SystemState s);
~CognitiveEntity ();
template <typename T> void RegisterChange (std::string context, T value);
bool operator!= (const CognitiveEntity& rhs) const;
private:
FuzzyCognitiveMap m_fuzzyCognitiveMap;
SystemState m_systemState;
std::vector <SystemState> RunFuzzyCognitiveMap ();
};
As shown, a CognitiveEntity has a SystemState object, which in turn has a vector of Concept objects (only the most relevant lines are shown):
class SystemState
{
public:
SystemState ();
~SystemState ();
void AddConcept (Concept c) { m_L.push_back(c); }
std::vector <Concept> m_L;
};
Inside the CognitiveEntity::RegisterChange, I mark a Concept as a potential cause (by calling Concept::IsPotentialCause (bool) which merely sets a private member with the value passed):
template <typename T>
void
CognitiveEntity::RegisterChange (std::string context, T value)
{
std::string name = context.substr(context.find_last_of ("/") +1);
int pos = m_systemState.FindConcept(name);
if (pos > -1)
{
int intValue = value ? 1 : 0;
m_systemState.m_L[pos].SetConceptValue (intValue, false);
if (m_systemState.m_L[pos].CheckVariation ())
{
m_systemState.m_L[pos].IsPotentialCause (true); // Mark this concept as a potential cause
for (int cause = 0; cause < m_systemState.GetSize (); cause++)
{
if ( (cause != pos) && (m_systemState.m_L[cause].MayBeCause ()))
{
m_fuzzyCognitiveMap.UpdateFuzzyCognitiveMapEntry (cause, pos, m_systemState);
m_systemState.m_L[cause].IsPotentialCause (false);
}
}
}
}
}
What happens is that as soon as RegisterChange is called another time, the Concept that was marked as potential cause, is marked no more.
I tried running gdb and I am sure that that member is not set elsewhere.
I'm not sure if this little information is enough for you to give me some hints about such a behavior (I didn't want to flood the post with the code of both SystemState and Concept classes).
Regards,
Jir
If this was a multi-threaded system, I'd say it sounds like a classic case of shared, mutable state that wasn't properly synchronized.
If you don't have a multi-threaded situation, I'd say set a watch on that variable and see what changes it.
Turns out the problem lied in how the code was called from within the network simulator (the code was meant to be used in the "ns-3" network simulator).
So, the problem wasn't even in the code I posted, and yet you managed to help me find the solution: thanks to the suggestions you gave me, I prepared a standalone version of the code and I watched the variable.
The problem was how I was passing the object.
Specifically, instead of passing around the object by reference (as I thought I was doing) I should have used smart pointers.
Thank you all for the great insights!
(and sorry for the mess... next time I'll be more accurate!)