有没有使用公共虚拟方法的正当理由?

use*_*542 3 c++ polymorphism c++11

有没有使用公共虚拟方法的正当理由?

我已经阅读过某个地方,我们应该避免使用公共虚拟方法,但我想向专家确认这是否是有效的声明?

seh*_*ehe 7

对于良好且稳定的API设计,非虚拟接口是一个很好的习惯用法.

我将按照现有的优秀文献推荐:

另见这些精彩的答案:

(Sumant Tambe 在他的博客上有一个有趣的设计意图含义矩阵,其中有一些关于设计意图的内容.)


Die*_*ühl 5

使virtual函数非公共允许基类围绕它们创建协议.如果没有别的,这可以用于需要仅基类的检测的一些会计/分析.基类公共接口可以是inline仅转发到virtual函数的函数.遗憾的是,可以在派生类中放宽限制,即,派生类可以virtual从基类提供对函数的公共访问.

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

这个答案讨论了为什么virtual函数不应该public.你是否应该首先使用virtual函数是一个单独的问题,有一些不平凡的答案.


Spo*_*ook 1

我想到一件事 - 不使用公共虚拟方法可以简化类接口与实现的分离。假设您提供了一个公共方法来做某事:

public:
    virtual void DoSth()
    {
    }
Run Code Online (Sandbox Code Playgroud)

一段时间后,引入了更改,这需要在执行某些操作之前初始化和完成基类。如果您已经从类中派生了一些类,则必须更改它们的实现。但如果你按照以下方式编写:

protected:
    virtual void InternalDoSth()
    {
    }

public:
    void DoSth()
    {
        InternalDoSth();
    }
Run Code Online (Sandbox Code Playgroud)

只需更改 DoSth 的实现即可:

public:
    void DoSth()
    {
        InitializeSth();
        InternalDoSth();
        FinalizeSth();
    }
Run Code Online (Sandbox Code Playgroud)

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