A famous quip says that C++ is the language in which friend s have access to your private parts.

But is it only friends?

When writing an RAII object I was feeling a bit lazy (which as we know is a virtue) and was surprised to discover that a local class (a class defined in a function body) has access to its enclosing class’s private members.

class outer { int private_ ; public : outer ( ) : private_ ( 0 ) { } void print ( ) { cout < < private_ < < endl ; } void foo ( ) { class local { // RAII object outer * outer_ ; public : local ( outer * p ) : outer_ ( p ) { outer_ - > private_ + + ; } ~ local ( ) { outer_ - > private_ - - ; } } ; print ( ) ; // -> 0 { // Scope for RAII object local in ( this ) ; print ( ) ; // -> 1 } print ( ) ; // -> 0 } } ;

A quick look through the standard didn’t show where such behaviour is specified but it compiled with all the compilers I threw it at[1].

When I revealed this discovery to my cow-orkers they responded with an empathic “DUH!” Oh well there goes my C++ geek-cred :o(

Allowing local classes access to private members makes a lot of sense on the language design front, after all if you can create a class in a method you should be able to do anything the method can do. I just never thought of it before and apparently I’m not the only one. When looking at C++11’s standard (well the final draft actually) I found the following in section 11 (Member access control):

A member of a class can also access all the names to which the class has access. A local class of a member function may access the same names that the member function itself may access.

Since this sentence does not appear in the original ’98 standard I can only assume that greater minds than mine had also missed this point, at least at first.

Having classes which can access your private parts can be very useful, they can be used for temporarily changing state (as in the RAII class above) or they can be used as parameters to STL algorithms[2]. The problem is that having a local class breaks the flow of the function and a nested class must be defined in the header so that something which is an implementation detail becomes globally visible.

But wait, the section in the standard had a footnote. “Access permissions are thus transitive and cumulative to nested and local classes.”

Transitive, that implies more than one level, this gave me an idea for a new(?) C++ pattern. I don’t know if I’m the first who thought of it and I doubt it’s very useful but here goes, I’m very proud to introduce the nested2 pattern.

For every class we can create a backdoor class that allows creation of quasi-friend classes. Then if the need arises we can add these quasi-friend classes in the .cpp file.

// .h file class troy { class wooden_horse ; int private_ ; public : troy ( ) ; void foo ( ) ; } ; // .cpp file class troy :: wooden_horse { public : struct odysseus { troy * t_ ; odysseus ( troy * p ) : t_ ( p ) { t_ - > private_ + + ; } ~ odysseus ( ) { t_ - > private_ - - ; } } ; // Add Greek warriors as needed } ; troy :: troy ( ) : private_ ( 41 ) { } void troy :: foo ( ) { wooden_horse :: odysseus odysseus ( this ) ; cout < < private_ < < endl ; }

By making the backdoor class private we can be sure that the quasi-friend classes won’t be abused since nobody but our class will be able to create an object of this type.

Edit: Ever since I posted this I couldn’t sleep at night, I knew I would never forgive myself if I don’t to this:

: % s / troy / french _ castle / g : % s / wooden _ horse / large _ wooden _ badger / g : % s / odysseus / bedemir / g : % s / Greek warriors / Knights of the round table / g : wq

[1] VC8, VC10, gcc, clang and Comeu (yes I am a bit obsessive, why do you ask?) ↩

[2] Although this is less compelling since the introduction of lambda expressions in C++11. On second thought, since lambda functions are implemented as unnameable classes perhaps this is the reason for the change in the standard, to allow lambda functions the same access rights as the method that defined them. ↩