My friend has shown me the follow code
struct A {
virtual void f() = 0;
virtual void g() = 0;
};
struct AInternal : A {
virtual void f() { /* ... */ }
virtual void g() { /* ... */ }
};
He is using AInternal
as an internal class that implements most (if not all of A
). He then inherited from AInternal
, but as he wanted that AInternal
stays inaccessible (since it is an implementation detail), he inherits protected (implemented in terms of). What he also did was using
ing the base class name to make A
accessible (it was protected by default, since AInternal
was inherited protected too)
struct C : protected AInternal {
using AInternal::A;
};
Actually, this worked fine (but as we later found, it still kept the member functions private
- just the base class was made public
), but it only worked on GCC. It fails to make base A
accessible. Any idea? We could even make it to break code that works on Clang
struct C : public AInternal {
protected:
using AInternal::A;
};
C *c = 0;
A *a = c; // error on GCC!
Can someone help out please?
Private members of the base class cannot be used by the derived class unless friend declarations within the base class explicitly grant access to them.
Classes derived from a base class are called child classes, subclasses or derived classes. A base class does not inherit from any other class and is considered parent of a derived class.
The derived class inherits all members and member functions of a base class. The derived class can have more functionality with respect to the Base class and can easily access the Base class. A Derived class is also called a child class or subclass.
The base class that is accessed is the base class specified in the class declaration. For example, if you specify class ClassB : ClassA , the members of ClassA are accessed from ClassB, regardless of the base class of ClassA.
You are only affecting the visibility of the injected-class-name. The access protection of the base subobject or its members should not be affected. If Clang or GCC allows it to affect a cast validity or access within the base, that's their bug.
[class.member.lookup] 10.2/3 says
In the declaration set, using-declarations are replaced by the members they designate, and type declarations (including injected-class-names) are replaced by the types they designate.
The base class subobject does not have a name in member lookup; the injected-class-name does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With