I am learning a little C ++, and now I am struggling with it, agreeing with Java.
First of all, remember that C ++ nested classes are similar to what you call static nested classes in Java. There is nothing in C ++ syntax to reproduce Java nested classes.
I found that the private attributes of the "container" class are not visible by the inner class ...
C ++ 98
In C ++, inner classes are no different from ordinary classes, they are not members of the class, then they cannot access the private members of the container class (unlike other languages ββsuch as Java or C #).
C ++ 03
Nested classes are members of the class, but restrictions on access to them still apply (see also the Strange Things section at the end of this answer). It was considered a standard defect (see DR45 ), then some compilers previously implemented the C ++ 0x access rule earlier, even when compiling for C ++ 03 (especially GCC, thanks to Jonathan Wackel to find out).
C ++ 11
This rule has changed in C ++ 11, now nested classes can access the private member of the container class. From Β§11.7:
A nested class is a member and, as such, has the same access rights as any other member.
Of course, you still need an instance to access non-stationary members.
... so why should I use them?
Then they are implementation details for grouping related classes, and they have the same problems with their use that may exist in other languages ββ(clarity for beginners, primary). IMO's greatest benefit is encapsulation if, for example, you have this:
class stream { virtual void write(const std::string text) = 0; }; class channel { public: virtual stream* get_stream() = 0;
In some cases, they are also useful for replacing nested namespaces:
class protocol { public: virtual void create_connection() = 0; class tcp : public protocol { }; class shared_memory : public protocol { }; class named_pipes: public protocol { }; }; auto media = protocol::tcp();
Or, to hide implementation details:
class file_system_entry { public: class file : public file_system_entry { }; class directory : public file_system_entry { }; std::time_t get_last_modified() { ... } void remove() { ... } virtual void copy_to(std::string path) = 0; private: class local_handle {
There are many other usage patterns (see also Why would you use nested classes in C ++? For a more convenient discussion), just remember that not everyone will correctly understand (and use!) Them. See Also Pros and Cons of Using C ++ Nested Classes and Enumerations?
Also, is there a way to make these attributes visible?
Before C ++ 11, you cannot (of course, if you do not declare them as friend , but see the next paragraph), if you need this function, just use the C ++ 11 compiler (which supports this function). GCC does (a long time ago) as well as MSVC, I don't know about other compilers.
Nested friends
Is there any difference between C ++ 11 access rules and friend classes? In general, they are almost equivalent (automatic access is only less detailed):
class container { public: class nested; friend class nested; class nested { }; };
Compared with:
class container { public: class nested { }; };
However, with forward declaration you have some side effects. Also remember that in terms of accessibility they are equivalent (access, like friendship, is neither inherited nor transitive). These examples do not compile:
class external : public container::nested { public:
Does it fully equivalent ? No , because private members of container friends are available in nested if it is a nested class in C ++ 11, but it is not so if nested is another container . Given this outlined structure:
class container; class another { friend class container; }; class container { public: class nested { }; };
nested can access another private member:
void container::nested::foo(another obj) { obj.somePrivateMember = 0; }
This works because nested is a member of container , then the transitive friendship constraint does not apply. Before C ++ 11, declaring nested as a friend of container , this code will not compile because friendship is not transitive.
Strange things
Suppose we can always declare a nested class as a friend of our container? Actually standard specified (SO / IEC 14822: 2003 (E), 11.8):
A friend of a class is a function or class that is not a member of the class ...
Then we will not be able to declare nested as a friend of container : in C ++ 03, nested classes are members of the class (but the standard clearly says that they do not have access to ordinary containers, nor can they be friends of the container class). There seemed to be no hope, fortunately, most compilers allowed us to do this (regardless of what the standard said).