NVI(Non-Virtual Interface)和Template Method模式之间有什么区别?
它们看起来非常相似,而且我已经读到它们基本相同,并且它们与模板在某种程度上更加通用有些微妙的不同。
答案 0 :(得分:11)
NVI是一种习惯用语,模板方法是一种模式。 NVI是使用C ++中的动态分派的模板方法模式的实现;也可以使用模板元编程在C ++中创建模板方法,以消除动态调度。
模式比成语更通用,语言可能使用不同的习语来实现模式。
答案 1 :(得分:9)
如前所述,NVI是一种与一类语言相关的编程习语。它由Herb Sutter等人推广,因为它有助于执行合同:
然而,实现可能实际上有很大不同,例如NVI实现的另一个例子是将它与Pimpl结合起来:
class FooImpl;
class Foo
{
public:
enum type { Type1, Type2 };
Foo(type t, int i, int j);
int GetResult() const;
private:
FooImpl* mImpl;
};
对于实施:
struct FooImpl
{
virtual ~FooImpl();
virtual int GetResult() const;
};
class FooType1: public FooImpl
{
public:
FooType1(int i, int j);
virtual int GetResult() const;
private:
/// ...
};
我总是发现它更好地传达了这一点。你明白了吗?
重点是virtual
是一个实现细节。在界面中公开实现细节是个坏主意,因为您可能希望更改它们。
此外,实现细节往往会破坏二进制兼容性。例如,在类中添加新的virtual
方法可能会更改虚拟表的布局(常见的实现技术),从而破坏二进制兼容性。在gcc上,如果你想保持兼容性,你需要确保你最后添加它(在虚拟中)。
通过使用上面的NVI + Pimpl组合,暴露的类中根本没有virtual
(甚至不是私有)。内存布局是向后和向前兼容的。我们已经实现了二进制兼容性。
在这里,我们一次使用多种模式: