Forbid child from invoking parent's abstract (or virtual) function

Viewed 119

I have a parent class that invokes a callback that is abstract. The child class is meant to override this callback, but must never call it on its own from its code.

class Parent(){
   public:
   void Init(){ MyCallback(); }

   protected:
   virtual void MyCallback() = 0;//child must override, but child must never call it manually.
};


 class Child : public Parent{
     protected:
     void MyCallback()override{  }

     private:
     void SomeCode{ MyCallback(); }//<---how to prevent this?
 } 

There are many callbacks such as these. I don't want the user to get lost and think that he should call any of them manually.

Is it possible to prevent these callbacks from being invoked by child class?

2 Answers

I don't think there is a way to enforce the rules you want at compile-time, but you can enforce them at runtime via assertion-failures, which is the next-best thing, since at least anyone who breaks the rule will learn the error of their ways the next time they run the program. Note that I've added a requirement that the subclass-overrides of MyCallback() must call up to the superclass-method exactly once, to prevent subclasses from gratuitously making additional calls to MyCallback() on themselves or their superclasses inside the callbacks-are-allowed context.

#include <stdio.h>
#include <stdlib.h>

class Parent
{
public:
   Parent() : _okayToCallCount(0), _numParentClassCallsMade(0) {/* empty */}

protected:
  virtual void MyCallback() 
  {  
     if (_okayToCallCount == 0) {printf("MyCallback() was called from an invalid context!\n"); abort();}
     _numParentClassCallsMade++;
     if (_numParentClassCallsMade > 1) {printf("Parent::MyCallback() was called more than once from the subclass's override-method!\n"); abort();}
  }   

private:
   // This is the only place that MyCallback should EVER be called from!
   void TheOnlyPlaceThatMyCallbackShouldEverBeCalledFrom()
   {  
      _numParentClassCallsMade = 0;

      _okayToCallCount++;
      MyCallback();
      _okayToCallCount--;

      if (_numParentClassCallsMade < 1) {printf("Parent::MyCallback() was never called from the subclass's override-method!\n"); abort();}
   }

   int _okayToCallCount;
   int _numParentClassCallsMade;
};

class Child : public Parent
{
public:
    Child() {}

    void SomeCode() { MyCallback(); }//<---how to prevent this?

protected:
    virtual void MyCallback()
    {  
       Parent::MyCallback();  // REQUIRED!
    }
};

int main(int argc, char ** argv)
{
   Child c;
   c.SomeCode();

   return 0;
}

Your Program had soo many mini Errors

class Parent(){     // These braces**()** don't come after a class's name
   public:
   void Init(){ MyCallback(); }

   protected:       // Because the datatype is protected, it can't be accessed properly (overrided) by **Main Function** 
   virtual void MyCallback() = 0;//child must override, but child must never call it manually.  
};


 class Child : public Parent{
     protected:
     void MyCallback()override{  }

     private:
     void SomeCode{ MyCallback(); }//<---how to prevent this?     // You forgot the braces here **()**
 }        // You forgot the semi-colon **;**

Here I have fixed them for you:-

#include <iostream> 
using namespace std; 

class Parent {
   public:
   void Init(){ MyCallback(); }

   //protected:
   virtual void MyCallback() = 0;//child must override, but child must never call it manually.
};


 class Child : public Parent{
     protected:
     void MyCallback()override{ cout <<"Child Class Function!";  }

     private:
     void SomeCode() { MyCallback(); }//<---how to prevent this?
 };

int main() 
{ 
    Parent* ptr_base; 
    Child derived; 
    ptr_base = &derived; 
    ptr_base->MyCallback(); 
}
Related