C++ private and protected virtual method和Is there any valid reason for not using public virtual methods?正在讨论非虚拟接口( NVI )和非公共虚拟功能及其共生关系 . Scott Meyers也在Effective C中说过
有时虚拟功能甚至必须是公开的,但是NVI惯用法无法真正应用 .
我没有看到为什么NVI要求特定于实现的虚拟功能是非公开的?从Herb Sutter的文章Virtuality开始,它是一个很好的做法,例如,将公共(客户端)接口与实现细节(非公共接口)分开是好的 . 我想知道的是,如果有任何语言功能我错过了语义上会阻止NVI被应用,如果这些虚拟功能被公开?
例如:
class Engine
{
public:
void SetState( int var, bool val );
{ SetStateBool( int var, bool val ); }
void SetState( int var, int val );
{ SetStateInt( int var, int val ); }
private:
virtual void SetStateBool(int var, bool val ) = 0;
virtual void SetStateInt(int var, int val ) = 0;
};
如果我将 SetStateBool
和 SetStateInt
放在类定义的公共部分中有什么影响?
2 回答
TLDR :你可以,但你不应该 .
假设您要确保正确记录对公共接口的每次调用(例如,金融服务法律要求)
由于公共接口是非虚拟接口,因此所有派生类也会自动进行日志记录 . 如果您将
SetStateBool
和SetStateInt
公开,则无法对所有派生类强制执行日志记录 .因此,使用NVI习语的建议不是语法要求,而是一种在所有派生类上强制执行基类语义(日志记录或缓存)的工具 .
不,语言中没有任何内容阻止您创建实现函数
public
. 原则上,您可以执行以下操作:实施是公开的 . 梅耶斯说,有时你必须这样做,他可能会说开发人员有时会受限于在设计不佳的环境中发展 .
例如,你可以反对RAII习语并做这样的事情:
析构函数实际上不会释放内存(是的,我之前必须处理这种类型的场景) . 该语言并不禁止它,但通常是一个坏主意 . 换句话说,仅仅因为它是合法的,并不意味着它是道德的(信用Marshall Cline)......而这就是成语的概念 .