【问题标题】:Is there any valid reason for not using public virtual methods? [closed]不使用公共虚拟方法有什么正当理由吗? [关闭]
【发布时间】:2014-03-24 06:44:55
【问题描述】:

不使用公共虚拟方法有什么正当理由吗?

我在某处读到我们应该避免使用公共虚拟方法,但我想从专家那里确认这是否有效?

【问题讨论】:

  • 由于派生可以简单地通过覆盖虚拟方法来篡改虚拟方法的访问限制,我真的很好奇该声明的作者在提出该声明时的想法。
  • 有,那是你不需要它们的时候。

标签: c++ c++11 polymorphism


【解决方案1】:

对于良好且稳定的 API 设计,Non-Virtual-Interface 是一个很好的习惯用法。

我将遵循现有的优秀文献:

另请参阅这些精彩的答案:

(Sumant Tambe 在他的博客上有一个有趣的矩阵 Design Intent Implications,其中包含更多关于设计意图的信息。)

【讨论】:

    【解决方案2】:

    virtual 函数设为非公共允许基类围绕它们创建协议。如果不出意外,这可以用于一些只需要检测基类的会计/分析。基类公共接口可以是inline 函数,只是转发给virtual 函数。遗憾的是,派生类的限制可以放宽,即,派生类可以公开访问基类中的virtual 函数。

    实际上还有另一个重要的原因使virtual 函数protected:重载virtual 函数时(例如,std::num_put<...> 中的do_put() 成员)很容易在仅覆盖一个时意外隐藏其他重载的功能。当virtual 函数既是自定义点又是调用接口时,这很容易导致令人惊讶的行为。当virtual函数为protected时,很明显调用接口和自定义接口实际上是不同的,即使直接使用派生类也可以避免问题。 virtual 函数可能希望成为 protected 以允许覆盖函数从基类调用默认实现。如果没有默认实现,virtual函数也可以是private

    这个答案讨论了为什么 virtual 函数不应该是 public。您是否应该首先拥有virtual 函数是一个单独的问题,答案有些不重要。

    【讨论】:

    • +1 实际花时间在现场解释:)。哦 and 最后一段 +1。值得一读。
    【解决方案3】:

    我想到一件事——不使用公共虚拟方法简化了类接口与实现的分离。比如说,你提供了一个公共方法来做某事:

    public:
        virtual void DoSth()
        {
        }
    

    一段时间后,引入了更改,这需要在做某事之前初始化和完成基类。如果您已经从您的类派生了一些类,则必须更改它们的实现。但是如果你是这样写的:

    protected:
        virtual void InternalDoSth()
        {
        }
    
    public:
        void DoSth()
        {
            InternalDoSth();
        }
    

    这只是改变 DoSth 的实现的问题:

    public:
        void DoSth()
        {
            InitializeSth();
            InternalDoSth();
            FinalizeSth();
        }
    

    创建两级虚函数非常便宜,并且为您提供了一个额外的层,这使您可以轻松控制将来调用虚方法的方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      • 2010-09-22
      • 1970-01-01
      相关资源
      最近更新 更多