Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"using" with base class name to change access valid?

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 usinging 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?

like image 259
Johannes Schaub - litb Avatar asked Jul 14 '13 17:07

Johannes Schaub - litb


People also ask

Can derived class access private members of base?

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.

Can base classes inherit from another base class?

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.

What can be inherited by a derived class from a base 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.

What is base class in C# with example?

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.


1 Answers

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.

like image 121
Potatoswatter Avatar answered Sep 29 '22 07:09

Potatoswatter