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?
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With