NVI(Non-Virtual Interface)和Template Method模式有什么不同?C++:NVI和模板方法模式之间的区别?
他们似乎非常相似,我读过两个,他们是基本相同的,他们是用模板是莫名其妙更一般的微妙的不同。
NVI(Non-Virtual Interface)和Template Method模式有什么不同?C++:NVI和模板方法模式之间的区别?
他们似乎非常相似,我读过两个,他们是基本相同的,他们是用模板是莫名其妙更一般的微妙的不同。
NVI是一个成语,模板方法是一个模式。 NVI是在C++中使用动态分派的模板方法模式的实现;还可以使用模板元编程在C++中创建模板方法以消除动态分派。
模式是比成语更一般的,和语言可以使用不同的习语来实现图案。
所以你是说NVI基本上是模板方法模式的语言特定实现,除此之外,没有真正的区别吗?你将如何使用C++模板来实现相同的结果? – 2010-07-19 20:59:03
@Robert S. Barnes据我所见,使用C++模板作为模板方法没有明显的方法。模板方法说'做这个,然后做这件事',虽然你可以为其中一件或另一件事创建一个函子,但是与C++模板给你的类型参数没有真正的关系。 – 2010-07-20 19:57:53
我想我仍然不明白你在这里的意思:“也可以使用模板元编程在C++中创建模板方法来消除动态分派。” – 2010-07-21 08:51:19
正如人们所说的,NVI是一个预设电台的成语,相关的语言种类。它已经在其他推广由Herb萨特,因为它有助于执行合同:
然而,实现实际上可能差异很大,例如NVI的另一个例子执行是将它与平普尔结合:
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 +平普尔组合,存在露出的类没有virtual
在所有(甚至没有公开)。内存布局是向后兼容的。我们已经实现二进制兼容。
在这里,我们使用几种模式一次:
+1为“虚拟是实现细节”和ABI考虑。 – neuro 2010-06-21 09:43:29
+1。但是,我不同意你为虚拟接口制作单独的类似pimpl的类。最明显的缺点是它会使所需班级的数量增加一倍。此外,如果FooImpl不透明,它可能会诱使用户直接使用它并跳过Foo。然而,由于NVI允许人们重写虚拟实现,所以它不太可能不透明,所以FooImpl将不得不公开访问。尽管它有其自身的缺点,但我认为在一个班级实施NVI并避免使用公共虚拟功能是一种更好的方法。 – stinky472 2010-06-30 07:56:27
这也是一个更容易实施的策略:没有公共虚拟函数,而是为提供公共虚拟接口的类pimpl类提供特殊情况。 – stinky472 2010-06-30 07:58:07
我不会使用维基百科链接作为参考,它们对锁的使用在异常情况下很脆弱...... – 2010-06-20 10:58:57