use*_*414 16 c# c++ design-patterns non-virtual-interface
在设计界面时,有人建议使用非虚拟界面模式.有人可以简要介绍一下这种模式的好处吗?
Pet*_*der 33
非虚拟接口模式的本质是您具有私有虚拟功能,这些功能由公共非虚拟功能(非虚拟接口)调用.
这样做的好处是,基类可以控制其行为,而不是派生类能够覆盖其接口的任何部分.换句话说,基类(接口)可以提供有关其提供的功能的更多保证.
举个简单的例子,考虑一下这个有着几个典型派生类的好老动物类:
class Animal
{
public:
virtual void speak() const = 0;
};
class Dog : public Animal
{
public:
void speak() const { std::cout << "Woof!" << std::endl; }
};
class Cat : public Animal
{
public:
void speak() const { std::cout << "Meow!" << std::endl; }
};
Run Code Online (Sandbox Code Playgroud)
这使用了我们习惯的常用公共虚拟接口,但它有一些问题:
std::cout << ... << std::endl;样板代码.speak()做.派生类可能会忘记新行,或将其写入cerr任何内容或其他任何内容.要解决此问题,您可以使用非虚拟接口,该接口由允许多态行为的私有虚拟函数补充:
class Animal
{
public:
void speak() const { std::cout << getSound() << std::endl; }
private:
virtual std::string getSound() const = 0;
};
class Dog : public Animal
{
private:
std::string getSound() const { return "Woof!"; }
};
class Cat : public Animal
{
private:
std::string getSound() const { return "Meow!"; }
};
Run Code Online (Sandbox Code Playgroud)
现在,基类可以保证它将std::cout以新行写出和结束.它还使维护更容易,因为派生类不需要重复该代码.
Herb Sutter写了一篇关于非虚拟接口的好文章,我建议你查看.