I am relatively new to C++, and I have looked a lot for an answer for this thing but I never got a satisfying answer.
Let's say I have a structure called FSM
. Eventually in my code, multiple instances of FSM
can be created. One of FSM
's attributes is int X
which is not static, every instance of FSM
should have its own value for X
.
Now, one of FSM
's attributes is another structure submachine
which needs to read the value of X
like this:
struct FSM
{
public:
int x;
int getX(){return x;}
struct submachine
{
void onentry() {int g = getX();};
};
};
This gives the following error:
Error: 'FSM::getX' : illegal call of non-static member function
My question is, submachine
is a member of FSM
, so shouldn't it have access to local instances of all the attributes of FSM
? And if not, when we create an instance of FSM
, wouldn't we be creating an instance of all its members i.e. submachine
? And if so, then why do we need to create an object that onentry()
needs?
I am assuming the compiler is correct, so I would also want to know if there's a way to make this work.
NOTE: Unfortunately, the instances of the inner structures (submachine
) are instantiated when an event is called and thus I can only define the type, and not instantiate objects for them in FSM
.
my question is, submachine is a member of FSM, so it should have access to local instances of all the attributes of FSM, no?
No. Unlike in Java, inner class objects don't have an implicit reference to an outer object.
wouldn't we be creating an intance of all its members i.e. submachine?
submachine
is a type, not a member variable. If you wanted a member variable, you'd have to do something like this:
struct FSM {
struct submachine {
...
};
submachine sm; // Member variable of type submchine
};
And if you want sm
to "see" its parent object, you'll need to pass it explicitly:
struct FSM {
struct submachine {
FSM &parent; // Reference to parent
submachine(FSM &f) : parent(f) {} // Initialise reference in constructor
};
submachine sm;
FSM() : sm(*this) {} // Pass reference to ourself when initialising sm
};
Note that the same principle applies for instances of submachine
that aren't member variables. If you want them to be able to access an FSM
instance, you'll need to pass a reference to one.
Note also that you could use a pointer rather than a reference. In fact, a pointer offers greater flexibility in many cases.