deleting or throwing compiler error when a virtual base function is called from a derived class in c++












-1















I have the following code:



 class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};

class B : public A
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};

class C : public A
{
public:
// do not want f(int a) accessible
void f(int a, int b);
};


I am aware that purely virtual functions cannot be deleted. Is there any way to disable these functions such that a compile time error occurs if an instance of B tries to call f(int,int) or when an instance of C tries to call f(int)










share|improve this question























  • Did you mean detecting instead of deleting (in the question title)?

    – François Andrieux
    Nov 23 '18 at 20:03













  • They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.

    – Matthieu Brucher
    Nov 23 '18 at 20:04






  • 1





    What would happen if it is called from A interface (B b; A& a = b; a.f(4, 2);)?

    – Jarod42
    Nov 23 '18 at 20:04













  • The nature of virtual is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement both A::f(int) and A::f(int, int) so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.

    – François Andrieux
    Nov 23 '18 at 20:05








  • 3





    This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?

    – StoryTeller
    Nov 23 '18 at 20:07


















-1















I have the following code:



 class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};

class B : public A
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};

class C : public A
{
public:
// do not want f(int a) accessible
void f(int a, int b);
};


I am aware that purely virtual functions cannot be deleted. Is there any way to disable these functions such that a compile time error occurs if an instance of B tries to call f(int,int) or when an instance of C tries to call f(int)










share|improve this question























  • Did you mean detecting instead of deleting (in the question title)?

    – François Andrieux
    Nov 23 '18 at 20:03













  • They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.

    – Matthieu Brucher
    Nov 23 '18 at 20:04






  • 1





    What would happen if it is called from A interface (B b; A& a = b; a.f(4, 2);)?

    – Jarod42
    Nov 23 '18 at 20:04













  • The nature of virtual is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement both A::f(int) and A::f(int, int) so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.

    – François Andrieux
    Nov 23 '18 at 20:05








  • 3





    This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?

    – StoryTeller
    Nov 23 '18 at 20:07
















-1












-1








-1








I have the following code:



 class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};

class B : public A
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};

class C : public A
{
public:
// do not want f(int a) accessible
void f(int a, int b);
};


I am aware that purely virtual functions cannot be deleted. Is there any way to disable these functions such that a compile time error occurs if an instance of B tries to call f(int,int) or when an instance of C tries to call f(int)










share|improve this question














I have the following code:



 class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};

class B : public A
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};

class C : public A
{
public:
// do not want f(int a) accessible
void f(int a, int b);
};


I am aware that purely virtual functions cannot be deleted. Is there any way to disable these functions such that a compile time error occurs if an instance of B tries to call f(int,int) or when an instance of C tries to call f(int)







c++ oop c++11 polymorphism virtual-functions






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 23 '18 at 20:02









basilbasil

3091722




3091722













  • Did you mean detecting instead of deleting (in the question title)?

    – François Andrieux
    Nov 23 '18 at 20:03













  • They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.

    – Matthieu Brucher
    Nov 23 '18 at 20:04






  • 1





    What would happen if it is called from A interface (B b; A& a = b; a.f(4, 2);)?

    – Jarod42
    Nov 23 '18 at 20:04













  • The nature of virtual is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement both A::f(int) and A::f(int, int) so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.

    – François Andrieux
    Nov 23 '18 at 20:05








  • 3





    This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?

    – StoryTeller
    Nov 23 '18 at 20:07





















  • Did you mean detecting instead of deleting (in the question title)?

    – François Andrieux
    Nov 23 '18 at 20:03













  • They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.

    – Matthieu Brucher
    Nov 23 '18 at 20:04






  • 1





    What would happen if it is called from A interface (B b; A& a = b; a.f(4, 2);)?

    – Jarod42
    Nov 23 '18 at 20:04













  • The nature of virtual is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement both A::f(int) and A::f(int, int) so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.

    – François Andrieux
    Nov 23 '18 at 20:05








  • 3





    This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?

    – StoryTeller
    Nov 23 '18 at 20:07



















Did you mean detecting instead of deleting (in the question title)?

– François Andrieux
Nov 23 '18 at 20:03







Did you mean detecting instead of deleting (in the question title)?

– François Andrieux
Nov 23 '18 at 20:03















They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.

– Matthieu Brucher
Nov 23 '18 at 20:04





They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.

– Matthieu Brucher
Nov 23 '18 at 20:04




1




1





What would happen if it is called from A interface (B b; A& a = b; a.f(4, 2);)?

– Jarod42
Nov 23 '18 at 20:04







What would happen if it is called from A interface (B b; A& a = b; a.f(4, 2);)?

– Jarod42
Nov 23 '18 at 20:04















The nature of virtual is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement both A::f(int) and A::f(int, int) so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.

– François Andrieux
Nov 23 '18 at 20:05







The nature of virtual is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement both A::f(int) and A::f(int, int) so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.

– François Andrieux
Nov 23 '18 at 20:05






3




3





This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?

– StoryTeller
Nov 23 '18 at 20:07







This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?

– StoryTeller
Nov 23 '18 at 20:07














2 Answers
2






active

oldest

votes


















1














There's no way to do that. You'd need a more complex class hierarchy. Something like this:



class A
{
public:
virtual ~A() {}
};

class BaseForB : public A
{
public:
virtual void f(int a) = 0;
};

class BaseForC : public A
{
public:
virtual void f(int a, int b) = 0;
};

class B : public BaseForB
{
public:
void f(int a) override
{
// details...
}
};

class C : public BaseForC
{
public:
void f(int a, int b) override
{
// details...
}
};





share|improve this answer

































    0














    One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:



    class A
    {
    public:
    virtual void f(int a) = 0;
    virtual void f(int a, int b) = 0;
    };

    class A_B : public A {
    using A::f;
    private:
    void f(int a, int b) final override {}
    };

    class B : public A_B
    {
    public:
    // do not want f(int a,int b) accessible
    void f(int a);
    };





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452375%2fdeleting-or-throwing-compiler-error-when-a-virtual-base-function-is-called-from%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      There's no way to do that. You'd need a more complex class hierarchy. Something like this:



      class A
      {
      public:
      virtual ~A() {}
      };

      class BaseForB : public A
      {
      public:
      virtual void f(int a) = 0;
      };

      class BaseForC : public A
      {
      public:
      virtual void f(int a, int b) = 0;
      };

      class B : public BaseForB
      {
      public:
      void f(int a) override
      {
      // details...
      }
      };

      class C : public BaseForC
      {
      public:
      void f(int a, int b) override
      {
      // details...
      }
      };





      share|improve this answer






























        1














        There's no way to do that. You'd need a more complex class hierarchy. Something like this:



        class A
        {
        public:
        virtual ~A() {}
        };

        class BaseForB : public A
        {
        public:
        virtual void f(int a) = 0;
        };

        class BaseForC : public A
        {
        public:
        virtual void f(int a, int b) = 0;
        };

        class B : public BaseForB
        {
        public:
        void f(int a) override
        {
        // details...
        }
        };

        class C : public BaseForC
        {
        public:
        void f(int a, int b) override
        {
        // details...
        }
        };





        share|improve this answer




























          1












          1








          1







          There's no way to do that. You'd need a more complex class hierarchy. Something like this:



          class A
          {
          public:
          virtual ~A() {}
          };

          class BaseForB : public A
          {
          public:
          virtual void f(int a) = 0;
          };

          class BaseForC : public A
          {
          public:
          virtual void f(int a, int b) = 0;
          };

          class B : public BaseForB
          {
          public:
          void f(int a) override
          {
          // details...
          }
          };

          class C : public BaseForC
          {
          public:
          void f(int a, int b) override
          {
          // details...
          }
          };





          share|improve this answer















          There's no way to do that. You'd need a more complex class hierarchy. Something like this:



          class A
          {
          public:
          virtual ~A() {}
          };

          class BaseForB : public A
          {
          public:
          virtual void f(int a) = 0;
          };

          class BaseForC : public A
          {
          public:
          virtual void f(int a, int b) = 0;
          };

          class B : public BaseForB
          {
          public:
          void f(int a) override
          {
          // details...
          }
          };

          class C : public BaseForC
          {
          public:
          void f(int a, int b) override
          {
          // details...
          }
          };






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 23 '18 at 20:22

























          answered Nov 23 '18 at 20:11









          Peter RudermanPeter Ruderman

          10.2k2352




          10.2k2352

























              0














              One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:



              class A
              {
              public:
              virtual void f(int a) = 0;
              virtual void f(int a, int b) = 0;
              };

              class A_B : public A {
              using A::f;
              private:
              void f(int a, int b) final override {}
              };

              class B : public A_B
              {
              public:
              // do not want f(int a,int b) accessible
              void f(int a);
              };





              share|improve this answer




























                0














                One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:



                class A
                {
                public:
                virtual void f(int a) = 0;
                virtual void f(int a, int b) = 0;
                };

                class A_B : public A {
                using A::f;
                private:
                void f(int a, int b) final override {}
                };

                class B : public A_B
                {
                public:
                // do not want f(int a,int b) accessible
                void f(int a);
                };





                share|improve this answer


























                  0












                  0








                  0







                  One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:



                  class A
                  {
                  public:
                  virtual void f(int a) = 0;
                  virtual void f(int a, int b) = 0;
                  };

                  class A_B : public A {
                  using A::f;
                  private:
                  void f(int a, int b) final override {}
                  };

                  class B : public A_B
                  {
                  public:
                  // do not want f(int a,int b) accessible
                  void f(int a);
                  };





                  share|improve this answer













                  One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:



                  class A
                  {
                  public:
                  virtual void f(int a) = 0;
                  virtual void f(int a, int b) = 0;
                  };

                  class A_B : public A {
                  using A::f;
                  private:
                  void f(int a, int b) final override {}
                  };

                  class B : public A_B
                  {
                  public:
                  // do not want f(int a,int b) accessible
                  void f(int a);
                  };






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 23 '18 at 20:41









                  Ian4264 Ian4264

                  13514




                  13514






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452375%2fdeleting-or-throwing-compiler-error-when-a-virtual-base-function-is-called-from%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Costa Masnaga

                      Fotorealismo

                      Sidney Franklin