Re: Why does the C++ spec. prohibit downcasting through non-public inheritance?
?? Tiib <ootiib@hot.ee> writes:
On 10 mai, 17:29, Paul Bibbings <paul.bibbi...@gmail.com> wrote:
<snip />
This doesn't sit comfortably with me as an `explanation'. ?I can
understand the points that you make about how non-public inheritence
is conventionally used and, again, with regard to how this use models
aggregation/composition. ?In itself, this is a design choice, idiomatic
even. ?What I'm not comfortable with is the thought of a language
incorporating limitations *merely* for the purposes of constraining
design. ?C++ is a multi-paradigm programming language and, as such, can
either be the wind in your sails or the stone in your shoe, depending on
how you use it. ?It doesn't seem to me to be a proper concern of the
language itself to forbid me from forming constructs and designs that
merely "do not make sense logically."
The whole set of public/protected/private access restrictions feels
like set of idiomatic design constraints. There are no real, physical
concerns why someone can not access private members. These are still
very important constraints to make the language better suitable for
object oriented programming. That is why i feel that most behavior
related to access restrictions is made especially for supporting
object-oriented conventions.
I can understand what you're saying here and, of course, my sense of
`unease' is not firmly grounded in anything that I could call support
for it.
Furthermore, I think that this mode of thinking in this instance is
inconsistent, since the same reasoning is not applied in preventing the
inverse `design error' of "casting from [whole] to [component]."
You should somehow be able to extract the component from whole. Up-
casting is the only operation that makes sense for doing it there.
There is sense in this too.
Although I am not the OP, I am as interested in the answer to this
question. ?For myself, I am perhaps wanting to hear how the downcast
from protected Base in the context of a member function of Derived is
disallowed for some reason that is `technical', so to speak; ?that it
would, perhaps, break encapsulation at some point `to the left' (so to
speak) of what, in its immediate context, appears to be a harmless cast.
Possibly there are better explanations. My opinion is just an opinion,
i can not immediately indicate any words of Stroustrup to back me up.
I wonder if this is one to take to comp.std.c++, or if the OP might wish
to do that.
In my own thoughts at the present I don't think that this is about
constraining design. ?I think that the alternative would, somehow,
*break* something. ?I just can't forsee what that might be. I am
wondering if it has something to do with bringing the complications of
multiple inheritance in to play.
That would be interesting, since the order in what the base classes
and members are constructed and also the order in what they are
located in memory seems same for all compilers and it does not
seemingly depend on access restrictions at all. There may be some sort
of optimization that such constraint allows, but i can not imagine it.
That does not matter of course since i can not imagine lots of things
that are possible. :D
Broadly, the kind of `scenario' I have in mind is something akin to the
example given (in a completely unrelated context) in [conv.qual]/4. To
quote the relevant text:
"[Note: if a program could assign a pointer of type T** to a pointer
of type const T** (that is, if line //1 below was allowed), a program
could inadvertently modify a const object (as it is done on line
//2). For example.
int main() {
const char c = 'c';
char* pc;
const char** pcc = &pc; //1: not allowed
*pcc = &c;
*pc = 'C'; //2: modifies a const object
}
--end note]"
Intuitively, for me at least, I found myself wondering what could be
wrong with assigning a pointer of type T** to a pointer of type const
T**. It was only from studying the example that it became clear *how*
it would break something else, "elsewhere," or "off to the left" as I
put it.
In short, I was wondering if there might not be a similar `loophole', if
you like, that would be opened in the case under question, were it
allowed to cast from protected Base in the context we are discussing.
In a very early post to this thread Alf made the suggestion that it
might permit accessing the protected base of an unrelated class in a
similar hierachy (IIRC). Though he retracted the details of the example
he presented, I am left wondering if there was not something in what he
was suggesting nevertheless - perhaps in a `diamond' hierarchy involving
virtual bases at some level, or something like that.
Regards
Paul Bibbings