![]() |
1
22
您已经想出了一些聪明的方法来实现这一点,代价是(正如您所承认的那样)使类膨胀,并添加代码来解决对象的责任,而不是程序员的不足。 真正的答案是在运行时不要这样做。这是程序员错误,不是运行时错误。 在编译时执行:如果语言支持,则使用语言构造,或者使用强制执行的模式( 例如, ,或者使编译依赖于通过的测试,并设置测试以强制执行。 或者,如果未能传播导致派生类失败,则让它失败,并显示一条异常消息,通知派生类的作者未能正确使用基类。 |
![]() |
2
13
您要寻找的只是非虚拟接口模式。 它与您在这里所做的类似,但是基类实现是 放心 因为它是唯一 可以 被召唤。它消除了上述示例所需的混乱。并且通过基类的调用是自动的,所以派生版本不需要进行显式调用。 谷歌“非虚拟界面”了解详情。 编辑 :在查找“template method pattern”之后,我发现它是非虚拟接口的另一个名称。我以前从来没听说过这个名字(我并不是gof粉丝俱乐部的持卡会员)。就我个人而言,我更喜欢使用非虚拟接口的名称,因为名称本身实际上描述了模式是什么。 再次编辑 :以下是NVI的方法:
|
![]() |
3
6
当只有一个继承级别时,可以使用 template method pattern 其中公共接口是非虚拟的并调用虚拟实现函数。然后基地的逻辑进入公共功能,这是肯定会被调用的。
如果您有不止一个继承级别,并且希望每个类都调用它的基类,那么您仍然可以使用模板方法模式,但有一个扭曲,
使虚拟函数的返回值只能由
这并不强制每个类调用 直接的 基类,它可能跳过一个级别(我想不出一个好的方法来执行它),但是它确实迫使程序员做出一个有意识的决定,换句话说,它是针对注意力不集中而不是恶意的。
如果你需要
注意事项:
|
![]() |
4
4
一种完全不同的方法是注册函子。派生类将在派生类构造函数中向基类注册某些函数(或成员函数)。当客户机调用实际函数时,它是基类函数,然后遍历已注册的函数。这可以扩展到许多级别的继承,每个派生类只需要关心自己的函数。 |
![]() |
5
0
看看模板 method pattern . (基本思想是您不必再调用基类方法。) |
![]() |
6
0
一种解决方法是完全不使用虚拟方法,而是允许用户注册回调,并在执行prepareForInsertion之前调用这些方法。这样就不可能犯这个错误,因为它是确保回调和正常处理都发生的基类。如果你想要这个行为有很多功能,你可以得到很多回调。如果你真的使用了这么多的模式,你可能想看看像AspectJ之类的工具(或者不管C等价物是什么),这样可以自动实现这类事情。 |
![]() |
7
0
如果您发现可以隐藏虚拟函数并使接口非虚拟,尝试检查其他用户是否调用了您的函数,只需自己调用即可。如果您的基本代码应该在最后调用,它将如下所示:
|
![]() |
rookie · 检查函数模板的所有参数包参数是否属于int 1 年前 |
![]() |
ivaigult · -W转换和隐式字符串到布尔类型转换 1 年前 |
![]() |
rainer · 后台插入程序的初始化 1 年前 |
![]() |
Community wiki · 以理智、安全和高效的方式复制文件 1 年前 |
|
Shefali Kanaujia · 对C中向量的向量进行排序++ 1 年前 |
|
Ma Joonyoung · 粗粒度和细粒度链表的时间比较 1 年前 |