Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inner class accessing outer class [duplicate]

Tags:

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.

like image 926
Kam Avatar asked Jul 10 '12 00:07

Kam


People also ask

Can an inner class access outer class methods?

An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance. To instantiate an inner class, you must first instantiate the outer class.

How does an inner class instance access the outer class members?

If you want your inner class to access outer class instance variables then in the constructor for the inner class, include an argument that is a reference to the outer class instance. The outer class invokes the inner class constructor passing this as that argument.

Can inner class access outer class private variables C#?

The inner class can access any non-static member that has been declared in the outer class. Scope of a nested class is limited by the scope of its (outer) enclosing class. If nothing is specified, the nested class is private (default). Any class can be inherited into another class in C# (including a nested class).

Can inner class access outer class public variables Java?

It can access any private instance variable of the outer class. Like any other instance variable, we can have access modifier private, protected, public, and default modifier.


2 Answers

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.

like image 145
Oliver Charlesworth Avatar answered Nov 15 '22 09:11

Oliver Charlesworth


consider that in your example, I can legally write a free function

void foo() {     FSM::submachine sub;     sub.onentry(); } 

where there is no FSM instance that sub could refer to.

Either, as Oli says, have the submachine object store a reference to its parent FSM object, or perhaps just pass the value of x directly into onentry (it isn't clear how it gets invoked).


From a quick look at the Boost.MSM docs I found this note on non-default-constructed submachines.

It's pretty ugly, I don't understand the backend enough to paraphrase it here, and the literal code won't make enough sense in isolation to be worth pasting.

The example code linked from there also shows the submachine's entry method with the following signature:

template <class Event,class FSM> void on_entry(Event const&,FSM& ); 

if that's accurate, you can either store a pointer to your outer state machine on_entry, or extract the value of x there and record it in the submachine.

like image 26
Useless Avatar answered Nov 15 '22 11:11

Useless