c++nested class accessing host private member

Recurring in stupid on-line MCQ interviews!

P185 ARM says a nested class NC can access static members of the enclosing class EC, and also local types of EC, all without fully qualified name.

However, NC can’t access EC’s non-static members. Java took a bold departure.

In c++11, a nested class is an implicit friend of the enclosing class. See https://stackoverflow.com/questions/5013717/are-inner-classes-in-c-automatically-friends

Advertisements

common nested types – dotnet^java^c++

Enum – is a common nested type in c++, java and dotnet. In java it’s typically a static nested “class” . In c++, non-nested enum is more common than nested enum

Delegate – is a common nested type in dotnet. Many textbook examples declare custom delegates nested in a class. However, in practice, it’s more common to declare it outside all classes – more reusable.

Local typedef – is a common nested “type” in c++

nested class having ptr to outer-class Object]java,c#,c++

Usually java is cleaner than c++ and c#. However, in this case I believe java is the Least clean.

Java “non-static nested class” feature is not “embraced” by Microsoft. All c# nested classes are static and can’t access non-static fields of the enclosing class.

C++ doesn’t support java style inner class either. See http://bigblog.tanbin.com/2009/03/nonstatic-nested-class-has-no-pointer.html

y a nested java class can only access final local variables

The explanation is tedious because it has to cover primitive/reference type local variables.

1) Primitive is easier. Say there’s local_boolean isGood variable. If it’s final, then the nested class can simply get an implicit isGood final_private_boolean_field when the nested instance (I’m not saying “class”) is allocated. Probably 1 byte added. All final primitive variables are immutable, which makes things simple.

2) Suppose this local variable is not final, and it’s accessed by a static or non-static NestedClass.m1(). At run time, when m1() runs, isGood is quite possibly out of scope if the stack frame is wiped out. The “last” value of isGood is lost.

3) Contrast 2) with a final_local_reference variable acct, with a mutable Boolean field acct.isGood. Final, so NestedClass instantiation can allocate a 32-bit immutable pointer to the object behind acct. This will put off the garbage collector. When NestedClass.m1() runs, the real time value of acct.isGood will be used, even though it’s mutable.

4) Now consider non-final_local_reference variable acct. acct can point at one object then another object. These objects are on heap, but the 32-bit local pointer is on stack. Stack frame could be gone when m1() runs. The address of the “last” object referenced by acct would be gone.

java singleton – y nested class implementation important

http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom is the recommended solution. My friend Rohan pointed out why this solution is sometimes necessary.

Say you can’t eagerly init the static field because it must wait for some service object.

Say you also don’t want to incur the static synchronization every time. Though un-contended lock acquisition is cheap, it’s never free.

c++ nested class experiment

#include
class Outer{
   int m_o;
   public:
   class Inner   {
      public:
        int m_i;
        Inner(){m_i=999;}
        Inner(Outer & m_outer, int x){
           m_outer.m_o = x; //against c++98
        }
   };
   Outer(int y)   {
       cout <m_inner.m_i<<" <—- this field is no-arg constructed.n";
       m_inner.m_i = y;
   }
   void Display()   {
       using namespace std;
       cout << m_o << endl
            << m_inner.m_i << endl;
   }
   Inner m_inner;
};
int main(){
   Outer    objOut(10); //inner == 10
   Outer::Inner objIn(objOut, 5); // objIn discarded, but objOut modified to 5
   objOut.Display();
   cin.get();
}

static nested classes unnecessary@@

As stated in another post, I always start my nested class as “private static” and relax gradually when justified.

Now, some say static nested classes can always be pulled out as first-class citizens i.e. top level classes. No. A major feature (perhaps 2) I rely on everyday is the private access modifier in the context of nested classes.

Nested class can refer to private members (fields/methods) of the enclosing class; enclosing class can refer to private members of the nested class.

java nested class — static^non-static

See post on [[philosophy of nested classes]].

Let’s put aside anon classes.

By default, all my nested classes start with the “static” keyword.

Practically, whenever the nested class needs access to enclosing class’s instance fields (outerInt1 for eg) i remove the “static” keyword and make the class non-static, effectively adding an implicit “outer.this” field into the nested class. Nested class can then access outerInt1 via outer.this.outerInt1

 

java private nested classes: my habits

A major justification and usage of nested class is constructor access control. To appreciate, first appreciate immutables, final, singletons, protected, …. Note you can finish most projects without using these access control devices, but I tend to spend extra time adding such access controls. In complex concurrent systems, they reduce risk and add much-needed reassurance. Constructor access control is one of the controls.

Majority of my nested classes have only private constructors. I usually call them from the enclosing class.

Furthermore, all my nested classes start off as private static classes, and become protected only when necessary.

public static nested class

XR

(another blog)

Just as constants can be defined in classes but better defined in interfaces, public nested static classes are better defined in interfaces. I feel this might be a best practice. It's more reusable and accessible.

More importantly, this is more readable than if defined in a class. When we define a public static nested class in an enclosing class, it appears to be tied to that class, but i feel that's an illusion. By putting the class in an interface, it's clearly presented as part of an open, shared interface and not tied to any object in the design.

However, i don't really know why we need public static nested classes at all. They look completely unnecessary.

In general, i feel anything that can go into classes or interfaces had better go into interfaces.

Coming back to nested classes, experts say static is better than non-static, if we have a choice. I agree, on the basis of readability, semantics, flexibility and loose coupling.

philosophy of java nested classes

“inner classes” = non-static nested classes. For beginners, let’s focus on typical scenarios:
1) C.java encloses N as a *private* inner class.
2) C.java has a field n1 of type N

Q: how would you use an instance of N? What does this object in memory represent?
A: a component of an object c (of type C).

Internalize — this.n1 is very similar to … a regular field, whereas N.class is more like a regular class than a C field. Allow me to repeat — Whenever you look at an inner class N, it’s very similar to a regular class.

Q: what does this.n1 resemble most? A field in an instance (c) of C?
A: No. Suppose a field j (of type J) in C has method j.m1(). m1() can’t (N can) access C’s private members
A: i think this.n1 most resembles a sophisticated and “trusted field“, a regular filed like j + the additional trust. The trust means this.n1 can have methods to access C’s private members.

Q: is such a construct never necessary and can be achieved using regular OO constructs?
A: No. The “trust” is hard to achieve otherwise.


Q: where do you instantiate N? How do you pass the instance around? How do you call N’s instance methods?
A: all inside C. Outside C, no other objects can see N

Q: how about a public (instead of private) inner class N2? What’s the use case or justification?
A: I would make N2’s constructor private, so outer class C.java is the only access point. So an instance (n2) of N2 becomes a slave object dedicated to the outer object. Note trust still applies.

——-
Now for static nested class S declared in C.java
Q: how would you use an instance of S? What does this object in memory represent?
A: not part of a C instance.
Q: what does this instance resemble most? A static field in an instance (c) of C?
A: No. I think in some usages this instance most resembles a better static method wrapper. You can group static methods in C and move them into S and make them non-static [1] inside S. An alternative design is the System.out pattern –. put (converting to non-static) C’s static methods [2] into a regular class A, and create an A instance as C’s static field. However, static nested class S (not A) can access C’s private static members.
A: in the case of AbstractMap.java, static nested class resembles….?

[2] they lose access to C’s private static members.

[1] I think most methods in S should be non-static. Static methods in a static nested class is a waste of time.

Q: where do you instantiate S? How do you pass the instance around? How do you call S’s instance methods?
A: instantiate in a static method in C. You can also do so in a static initializer or a non-static method.

nested class has special capabilities ] C++^java

Q: Can nested class (NN) methods access a private member of the enclosing class EE? See c++nested class accessing host private member

Can EE methods access NN’s private members? Yes. Tested. See below.

Below is based on P186 ARM, perhaps outdated.
Q: in terms of syntax, how does Inner class methods refer to Outer class’s non-static[1] field?
A: no special access. Unlike java, there’s no hidden “this” field pointing to the Outer _i n s t a n c e_
A: yes if the Inner method has a pointer, reference or a nonref variable of an Outer class _i n s t a n c e_,

Java’s nested class N1 is in the same “private club” along with E2() an Enclose class private method.
– N1 methods can access private members of E2
– E2 methods can access private members of N1
–> Not in C++

Q: So what special capabilities does a nested class has? Why make a class nested at all?
A: to mention the “Inner” type name, you need to prefix it as “Outer::Inner”
A: another specialness — inner class methods can access outer private members. As pointed out on
http://stackoverflow.com/questions/1604853/nested-class-access-to-enclosing-class-private-data-members
— in the original C++98 the inner class has no special privileges accessing the outer class.With C++98 compiler you’d either have to give the inner class the necessary privileges (friendship) or expose
the outer members x and y as public. However, this situation was classified as a defect in C++98, and it was decided that inner classes should have full access to outer class members (even private ones).

[1] static is fine — Outer::f

c++ nested class has NO ptr to enclosing-class object

See also the post in the recrec blog that’s dedicated to the same topic.

Q: Does a non-static nested class have an implicit pointer to the enclosing-class object [1]?

Specifically, say Class O defines a non-static nested class N, and has a non-static field n1 of type N. Given an object o2 of type O, in java, n1 has an implicit pointer to the o2 object. Not in C++. See P790 [[c++ primer]] and P187 ARM.

[1] and can access the non-static fields and methods of the enclosing object?

Q: what’s the difference between static vs non-static nested class in c++?