"Alf P. Steinbach" <al***@start.no> wrote in message
news:43*****************@news.individual.net
* Victor Bazarov: Alf P. Steinbach wrote: #include <iostream>
struct Belcher
{
int x;
void belch() { std::cout << x << std::endl; }
Belcher( int anX ): x( anX ) {}
};
struct Person: private Belcher { Person(): Belcher( 666 ) {} };
struct Viking: Person
{
void eat() {}
void dine( bool belch )
{
eat();
if( belch )
{
Viking* pv = this;
::Belcher* p = (::Belcher*) pv;
// Why is qualification necessary here?
By qualifying you explicitly specify to use the global name 'Belcher'
not the 'Belcher' name brought into the scope of this class from the
Person's scope -- the grandfather class. If you remember, a name in
scope _hides_ the name in the enclosing scope.
Well, yes, but it isn't really in scope in Viking when it's private in
Person, is it? I mean, that's an implementation detail of Person. It
shouldn't affect Viking, except for virtual member functions.
By 10.2, name lookup takes place before access control. If I have
interpreted this correctly, this means that the fact that Belcher is private
in Person is irrelevant for name lookup purposes.
What surprises me is that inheriting from Belcher apparently has the effect
of declaring a Belcher type that is distinct from the Belcher type declared
at global scope. But I guess this makes sense; after all a base subobject
can be of zero size, whereas a free-standing object of the same-named class
cannot be of zero size.
--
John Carson