C++ 中的接口最好写成抽象基类:包含至少一个纯虚函数的无状态类。具体类从接口类公开派生,并(可选)添加状态以实现接口。
class IFoo
{
public:
// enable deletion of implementation classes through IFoo*
virtual ~IFoo() {}
// interface
void bar()
{
// add optional pre-processing here
do_bar();
// add optional post-processing here
}
private:
// to be overridden by implementation classes
virtual void do_bar() = 0; // pure virtual
// no state here!
};
class FooImpl
:
public IFoo
{
public:
// constructors, assignment etc. to manipulate state
private:
virtual void do_bar()
{
// your implementation
}
// add your state here
};
void my_algorithm(IFoo* foo)
{
foo->bar();
}
int main()
{
IFoo* f = new FooImpl();
my_algorithm(f); // resolves to using FooImpl::do_bar()
return 0;
}
上面的代码是在运行时多态性和显式接口方面的。在 C++ 中有一个使用编译时多态性和隐式接口的替代方案。这是使用模板和 Curiously Recurring Template Pattern 完成的。
请注意,我在这里使用了非虚拟接口(NVI)成语:公共接口IFoo
是非虚拟的,实现是(纯)虚拟的。这为接口的编写者提供了更大的灵活性,例如在IFoo::bar()
客户不注意的情况下添加日志记录和其他检查等。