c++ - 禁止孩子调用父母的抽象(或虚拟)函数
问题描述
我有一个调用抽象回调的父类。子类旨在覆盖此回调,但绝不能从其代码中单独调用它。
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?
}
有很多这样的回调。我不希望用户迷路并认为他应该手动调用其中任何一个。
是否可以防止这些回调被子类调用?
解决方案
我认为没有办法在编译时强制执行您想要的规则,但是您可以在运行时通过断言失败来强制执行它们,这是次优的,因为至少任何违反规则的人都会学习他们下次运行程序时的方式错误。请注意,我添加了一个要求,即 MyCallback() 的子类覆盖必须只调用一次超类方法,以防止子MyCallback()
类在允许回调的上下文中无故对自己或其超类进行额外调用.
#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;
}
推荐阅读
- c - 了解 makefile 的依赖级别
- wordpress - 如何减少 Wordpress 中标题和 iframe 之间的空间?
- git - 处理来自 magit 扩展的交互式 git 命令
- python - 在 Google App Engine 中使用 ctypes 来使用二进制文件?
- python - pip 无法解析 require.txt 中的依赖关系
- php - Laravel 未定义方法
- python-3.x - 如何在执行该类的所有其他方法之前运行一次 pytest 方法
- mysql - SQL 行锁和事务
- octobercms - 是否可以更改开关的文本?
- sql - 如何在 Oracle 的 SQL 中使用 REGEXP_SUBSTR 将空槽替换为自定义消息