为什么首选非虚拟接口?

时间:2016-06-17 04:08:31

标签: c++ interface

我正在阅读Herb Sutter的这篇文章http://www.gotw.ca/publications/mill18.htm。作者提到,编写非虚拟接口将接口规范与“实现细节(即内部可自定义行为)”区分开来“

// Example 1: A traditional base class.
//
class Widget
{
public:
  // Each of these functions might optionally be
  // pure virtual, and if so might or might not have
  // an implementation in Widget; see Item 27 in [1].
  //
  virtual int Process( Gadget& );
  virtual bool IsDone();
  // ...
};

上面的示例指定了哪种实现细节(或可自定义的行为)?我对上面的代码有什么问题感到有些困惑,这需要我们使用非虚拟接口

2 个答案:

答案 0 :(得分:1)

customizable behavior表示由不同的Derived Classes提供的实现,即从Interface派生的类。

考虑一下:

class IMachine
{
    public:
        int ProcessJob()
        {
            cout << "Processing Job in By-Default way" << endl;
        }
        virtual int ProcessOrder()
        {
            cout << "Processing Order in By-Default way" << endl;
        }
};
class CMachine_A : public IMachine
{
    public:
        int ProcessJob()
        {
            cout << "Processing Job in Machine A's way" << endl;
        }
        int ProcessOrder()
        {
            cout << "Processing Order in Machine A's way" << endl;
        }
};
class CMachine_B : public IMachine
{
    public:
        int ProcessJob()
        {
            cout << "Processing Job in Machine B's way" << endl;
        }
        int ProcessOrder()
        {
            cout << "Processing Order in Machine B's way" << endl;
        }
};

IMachine *pMachine;
CMachine_A oMachineA;
CMachine_B oMachineB;

pMachine = &oMachineA;
pMachine->ProcessJob();
pMachine = &oMachineB;
pMachine->ProcessJob();

Output:
Processing Job in By-Default way
Processing Job in By-Default way

因此,在上面的示例中,即使pMachine指向不同的具体实现(读取:派生类),但无论选择的实现/派生类如何,输出都是相同的。也就是说,机器A和机器B的customizable behavior没有生效或没有兑现。因此,通过非虚拟 IMachine::ProcessJob(),接口IMachine已分离/忽略/禁止处理作业的方式,而不管计算机的类型({{使用的是1}}或CMachine_A

现在考虑一下:

CMachine_B

这里,当IMachine *pMachine; CMachine_A oMachineA; CMachine_B oMachineB; pMachine = &oMachineA; pMachine->ProcessOrder(); pMachine = &oMachineB; pMachine->ProcessOrder(); Output: Processing Order in Machine A's way Processing Order in Machine B's way 指向不同的具体实现(读取:派生类)时,输出是根据所选的实现/派生类。也就是说,机器A和机器B的pMachine即将生效或受到尊重。因此,通过虚拟 customizable behavior,接口IMachine::ProcessOrder()保持选项/方式打开,其中订单将根据计算机的类型进行处理({{1}使用的{或IMachine}。

简而言之,由于接口CMachine_ACMachine_B保持为IMachine,因此不同的实现/派生类可以为函数ProcessOrder提供virtual

答案 1 :(得分:0)

指定虚拟公共接口int Process( Gadget& );时,您还要限制扩展接口以匹配此公共接口。扩展此类的任何人都需要通过实现Process函数来实现此目的。

提供更清晰的公共界面和更适合[批量]精心设计的私人定制功能,可以单独解决我们的两个目标。