【问题标题】:Why does GoF advise using protected (as opposed to private) virtual methods in a C++ Template Method Pattern implementation?为什么 GoF 建议在 C++ 模板方法模式实现中使用受保护(而不是私有)虚拟方法?
【发布时间】:2012-03-25 01:10:16
【问题描述】:

来自四人组的模板方法模式:

三个实现问题值得注意:

  1. 使用 C++ 访问控制。在 C++ 中,模板方法调用的原始操作可以声明为受保护成员。这确保 它们仅由模板方法调用。原始操作 必须被覆盖的被声明为纯虚拟。模板方法 本身不应被覆盖;因此您可以制作模板 方法一个非虚拟成员函数。

“这确保它们只被模板方法调用。”不是真的,是吗?由于原始方法(例如,如果有些是虚拟的而不是纯虚拟的)也可以从派生类中调用。仅将原始方法声明为私有可确保它们仅由模板方法调用,这不是真的吗?然后,私有虚拟原始方法仍然可以在子类中实现(或重新实现),以提供在超类的模板方法中定义的算法中所需的特殊行为。

参见 Herb Sutter 的“虚拟”:

http://www.gotw.ca/publications/mill18.htm

他声明的地方:

准则 #2:倾向于将虚拟函数设为私有。 准则 #3:仅当派生类需要调用 虚函数,使虚函数受保护。

我在 GoF 模板方法模式中没有看到派生类调用虚函数的基类实现的任何要求,那么为什么四人组建议将这些函数设为受保护而不是私有?

【问题讨论】:

    标签: c++ design-patterns virtual template-method-pattern


    【解决方案1】:

    答案很简单:

    Design Patterns dates from 1994。此时,C++ 仍在大力发展为我们今天所熟知的语言——之前的标准于 1998 年完成!编译器有问题,不支持我们现在认为理所当然的重要功能。

    但更重要的是,很多东西还没有被发现(尤其是主流程序员)。以模板元编程为例,整个过程只是“偶然发现”around the same time

    我高度怀疑私有虚函数也是如此:GoF 根本不知道这是合法的 C++。或者,如果是的话,它还没有确立为惯例。

    事实上,即使不考虑 C++11,大多数在 1994 年被认为“好”的 C++ 代码在今天都被认为过于复杂且容易出错。

    【讨论】:

    • 历史观点或多或少是正确的——在 1995 年,我认为大多数 C++ 程序员都没有想到可以覆盖私有函数。 (std::streambuf 中的虚函数是受保护的,而不是私有的。)不过,即使在今天,我认为有些人更喜欢 protected 而不是 private 来使用这些函数。派生类当然必须知道它们,而对于那些人来说,private 意味着私有,至少对于人类读者来说是私有的,如果不是编译器的话。
    • @James 我可以证明这一点……直到最近我才意识到这是合法的,并且一开始发现它非常不直观……
    • 谢谢。我怀疑这是答案,但在问这个问题之前,我有 Stephen Dewhurst 的 C++ Common Knowledge (2005) 手头,这让我怀疑我缺少的受保护/私有论点还有更多的东西。它关于模板方法的章节提到它“通常”被实现为调用受保护的虚拟函数,它继续在代码示例中使用。它没有提及模板方法调用的原始函数的私有与受保护问题。
    猜你喜欢
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 2012-01-08
    • 2017-06-20
    相关资源
    最近更新 更多