access specifiers & class inheritance

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hallo experts,

I have a little problem with access specifiers for class inheritance, which can be demonstrated in the following example.

>>> EXAMPLE >>>
  
class A {
protected:
  int i = 0;
};
 
class B : private A {
private:
  int getValue() {
    return i;
  }
};
 
class C : private A, public B {
private:
  int getValue() {
    return i;
  }
};
 
<<< EXAMPLE <<<

This will eventually cause a compiler error, because allegedly in class C parameter i is ambiguous.

The standard clearly says (clause 11.2) that in class B all members of class A are privat to B, so they should not be visible to class C.
The problem seems to come from clause 10.2 in the specification that says that name resolution runs before(!) visibilty rules are applied.
I would say my example is slightly similar to the example given in 11.6, but I assume the virtual keyword makes some difference here. Am I right? Otherwise, I wonder why this should be ok, since f() would also be resolved twice.

Can anybody explain why I can have the same symbol when it's declared private in the class scope, but I can't if I make it private through inheritance? This is an ambiguity I don't understand.

thanks for your help
Michi
 
>>> ISO/IEC 14882:2011 >>>

[...] 10.2 Member name lookup [class.member.lookup]

Member name lookup determines the meaning of a name (id-expression) in a class scope (3.3.7). Name
lookup can result in an ambiguity, in which case the program is ill-formed. For an id-expression, name
lookup begins in the class scope of this; for a qualified-id, name lookup begins in the scope of the nested-
name-specifier. Name lookup takes place before access control (3.4, Clause 11). [...]
  
[....] 11.2 Accessibility of base classes and base class members [class.access.base]
 
If a class is declared to be a base class (Clause 10) for another class using the public access specifier, the
public members of the base class are accessible as public members of the derived class and protected
members of the base class are accessible as protected members of the derived class. If a class is declared to
be a base class for another class using the protected access specifier, the public and protected members
of the base class are accessible as protected members of the derived class. If a class is declared to be a base
class for another class using the private access specifier, the public and protected members of the base
class are accessible as private members of the derived class. [....]

[...] 11.6 Multiple access [class.paths]

If a name can be reached by several paths through a multiple inheritance graph, the access is that of the
path that gives most access. [ Example:
class W { public: void f(); };
class A : private virtual W { };
class B : public virtual W { };
class C : public A, public B {
void f() { W::f(); } // OK
};

Since W::f() is available to C::f() along the public path through B, access is allowed. [...]




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux