Question Regarding C++ Visibility
Okay, so in an examination of nested classes in C++, I came upon this interesting problem. The following code compiles with no warnings with "-Wall -Wextra -ansi -pedantic" on gcc and "-Wall -Wcheck" on icc, leading me to believe that it is valid C++.
Code:
#include <iostream> My question is, why should this work? Outer::Inner is private, so it's print member function should not be visible to main. Indeed, one does get a compiler error if one switches out the commented lines with the one above them. Any insight on why this is? Is there some situation I'm not foreseeing in which this behavior is desirable? |
Outer::dostuff() returns an Inner object. This object can call print, since it is allowed to access its own members. print() is actually public for this object; it is Inner which is private. main() can therefore call print() without any problems, though it is not allowed to declare a variable of type Inner, since it cannot "see" Inner. It works because C++ is weakly typed; instead of performing a typecheck on Outer::dostuff() at runtime, it just looks to see if it has a print() method, which it does. I'm pretty sure if you assigned Outer::dostuff() to a variable of type Object, or whatever C++'s basic object class is (sorry, I don't know much about C++), and then called print(), it wouldn't complain.
In other words, main() has no idea that it is calling Inner's print method, it is just calling something's print method. http://en.wikipedia.org/wiki/Weak_typing I'm pretty sure this would return a compiler error in a strongly-typed language like Ada or Java. |
Quote:
Quote:
Quote:
I guess my real question is not so much why this is valid C++ in terms of "which are the relevant parts of the specification", but rather what I mean to ask is "why would anyone ever want it to be legal for a visible function to return an instance of an invisible class"? |
Quote:
|
Quote:
I just wanted to see what C++ did, and the decision surprised me. I am by no means saying that C++ should not do it that way, I'm just trying to understand what its use case is, because if some useful design requires it, then I don't want the language I'm designing to forbid useful designs. However, if it is simply an oversight or an edge case that would be too complex to specify as invalid, then I won't worry about preserving the ability to do things like this. |
Quote:
Code:
#include <iostream> |
All times are GMT -5. The time now is 08:01 AM. |