Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding public virtual functions with private functions in C++

Is there is any reason to make the permissions on an overridden C++ virtual function different from the base class? Is there any danger in doing so?

For example:

class base {     public:         virtual int foo(double) = 0; }  class child : public base {     private:         virtual int foo(double); } 

The C++ faq says that it is a bad idea, but doesn't say why.

I have seen this idiom in some code and I believe that the author was attempting to make the class final, based on an assumption that it is not possible to override a private member function. However, This article shows an example of overriding private functions. Of course another part of the C++ faq recommends against doing so.

My concrete questions:

  1. Is there any technical problem with using a different permission for virtual methods in derived classes vs base class?

  2. Is there any legitimate reason to do so?

like image 734
Ben Martin Avatar asked Jan 27 '09 18:01

Ben Martin


People also ask

Can we override private virtual function?

A private virtual function can be overridden by derived classes, but can only be called from within the base class.

Can a virtual function be private?

A virtual function can be private as C++ has access control, but not visibility control. As mentioned virtual functions can be overridden by the derived class but under all circumstances will only be called within the base class.

Can virtual methods be overridden?

A virtual method is first created in a base class and then it is overridden in the derived class. A virtual method can be created in the base class by using the “virtual” keyword and the same method can be overridden in the derived class by using the “override” keyword.


2 Answers

You do get the surprising result that if you have a child, you can't call foo, but you can cast it to a base and then call foo.

child *c = new child(); c->foo; // compile error (can't access private member) static_cast<base *>(c)->foo(); // this is fine, but still calls the implementation in child 

I suppose you might be able to contrive an example where you don't want a function exposed, except when you are treating it as an instance of the base class. But the very fact that that situation pops up would suggest a bad OO design somewhere along the line that should probably be refactored.

like image 65
Eclipse Avatar answered Sep 21 '22 15:09

Eclipse


The problem is that the Base class methods are its way of declaring its interface. It is, in essence saying, "These are the things you can do to objects of this class."

When in a Derived class you make something the Base had declared as public private, you are taking something away. Now, even though a Derived object "is-a" Base object, something that you should be able to do to a Base class object you cannot do to a Derived class object, breaking the Liskov Substitution Prinicple

Will this cause a "technical" problem in your program? Maybe not. But it will probably mean object of your classes won't behave in a way your users expect them to behave.

If you find yourself in the situation where this is what you want (except in the case of a deprecated method referred to in another answer), chances are you have an inheritance model where inheritance isn't really modeling "is-a," (e.g. Scott Myers's example Square inheriting from Rectangle, but you can't change a Square's width independent of its height like you can for a rectangle) and you may need to reconsider your class relationships.

like image 45
JohnMcG Avatar answered Sep 19 '22 15:09

JohnMcG