Overriding public virtual functions with private functions in C++

前端 未结 7 517
隐瞒了意图╮
隐瞒了意图╮ 2020-11-27 02:51

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:

相关标签:
7条回答
  • 2020-11-27 03:18

    It can be done, and very occasionally will lead to benefits. For example, in our codebase, we are using a library that contains a class with a public function that we used to use, but now discourage the use of due to other potential problems (there are safer methods to call). We also happen to have a class derived from that class which a lot of our code uses directly. So, we made the given function private in the derived class in order to help everyone remember not to use it if they can help it. It doesn't eliminate the ability to use it, but it will catch some uses when the code tries to compile, rather than later in the code reviews.

    0 讨论(0)
  • 2020-11-27 03:19

    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.

    0 讨论(0)
  • 2020-11-27 03:20

    There's no technical problem, but you will end up with a situation where the publicly available functions will depend upon whether you have a base or derived pointer.

    This in my opinion would be weird and confusing.

    0 讨论(0)
  • 2020-11-27 03:25

    A good use-case for private inheritance is a Listener/Observer event interface.

    Example code for the private object:

    class AnimatableListener {
      public:
        virtual void Animate(float delta_time);
    };
    
    class BouncyBall : public AnimatableListener {
      public:
        void TossUp() {}
      private:
        void Animate(float delta_time) override { }
    };
    

    Some users of the object want the parent functionality and some want the child functionality:

    class AnimationList {
       public:
         void AnimateAll() {
           for (auto & animatable : animatables) {
             // Uses the parent functionality.
             animatable->Animate();
           }
         }
       private:
         vector<AnimatableListener*> animatables;
    };
    
    class Seal {
      public:
        void Dance() {
          // Uses unique functionality.
          ball->TossUp();
        }
      private:
        BouncyBall* ball;
    };
    

    This way the AnimationList can hold a reference to the parents and uses parent functionality. While the Seal holds a reference to the child and uses the unique child functionality and ignoring the parent's. In this example, the Seal shouldn't call Animate. Now, as mentioned above, Animate can be called by casting to the base object, but that's more difficult and generally shouldn't be done.

    0 讨论(0)
  • 2020-11-27 03:31

    It can be very useful if you are using private inheritance - i.e. you want to reuse a (customized) functionality of a base class, but not the interface.

    0 讨论(0)
  • 2020-11-27 03:39
    1. No technical problem, if you mean by technical as there being a hidden runtime cost.
    2. If you inherit base publically, you shouldn't do this. If you inherit via protected or private, then this can help prevent using methods that don't make sense unless you have a base pointer.
    0 讨论(0)
提交回复
热议问题