我正在阅读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();
// ...
};
上面的示例指定了哪种实现细节(或可自定义的行为)?我对上面的代码有什么问题感到有些困惑,这需要我们使用非虚拟接口
答案 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_A
将CMachine_B
保持为IMachine
,因此不同的实现/派生类可以为函数ProcessOrder
提供virtual
。
答案 1 :(得分:0)
指定虚拟公共接口int Process( Gadget& );
时,您还要限制扩展接口以匹配此公共接口。扩展此类的任何人都需要通过实现Process
函数来实现此目的。
提供更清晰的公共界面和更适合[批量]精心设计的私人定制功能,可以单独解决我们的两个目标。