Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing Function Access Mode in Derived Class

Consider the following snippet:

struct Base {   virtual ~Base() {}    virtual void Foo() const = 0; // Public };  class Child : public Base {   virtual void Foo() const {} // Private };  int main() {   Child child;    child.Foo(); // Won't work. Foo is private in this context.    static_cast<Base&> (child).Foo(); // Okay. Foo is public in this context. } 

Is this legal C++? "This" being changing the virtual function's access mode in the derived class.

like image 835
hlx236sk Avatar asked Jan 26 '10 17:01

hlx236sk


People also ask

Can we change access modifier overridden method in C++?

Yes, an overridden method can have a different access modifier but it cannot lower the access scope. Methods declared public in a superclass also must be public in all subclasses. Methods declared protected in a superclass must either be protected or public in subclasses; they cannot be private.

How do I change the access specifier in C++?

Changing the access of a class member (C++ only) To increase the access of a member x of class A inherited from class B , use a using declaration. You cannot restrict the access to x with a using declaration. You may increase the access of the following members: A member inherited as private .

Can derived classes access private members?

Derived class can not access the private members of it's base class. No type of inheritance allows access to private members.


2 Answers

This is legal C++, §11.6/1 says:

Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.

As you noted, Child::Foo() is thus still accessible via the base class, which is in most cases undesired:

 Child* c = new Child;  Base* b = c;  c->Foo(); // doesn't work, Child::Foo() is private  b->Foo(); // works, calls Child::Foo() 

Basically, the declaration you refer to in the expression dictates the access mode - but virtual functions undermine that as another function then the named one may actually be invoked.

like image 108
Georg Fritzsche Avatar answered Oct 14 '22 06:10

Georg Fritzsche


Yes, changing the access mode in derived classes is legal.

This is similar in form but different in intent to the Non-Virtual Interface idiom. Some rationale is given here:

The point is that virtual functions exist to allow customization; unless they also need to be invoked directly from within derived classes' code, there's no need to ever make them anything but private.

As to why you would actually make something public in base but private in derived without private or protected inheritance is beyond me.

like image 26
MSN Avatar answered Oct 14 '22 04:10

MSN