Why is it preferred to have non-virtual interfaces?

前端 未结 2 1490
臣服心动
臣服心动 2021-01-17 01:10

I am going through this article http://www.gotw.ca/publications/mill18.htm by Herb Sutter. The author mentions that writing non-virtual interfaces separates the interface sp

相关标签:
2条回答
  • 2021-01-17 01:25

    When you specify the virtual public interface, int Process( Gadget& );, you are also restricting the extension interface to match this public interface. Whoever extends this class will need to do this by implementing the Process function.

    Providing a cleaner public interface and a more suitable [batch] of well designed private functions for customization will allow tackling our two goals individually.

    0 讨论(0)
  • 2021-01-17 01:26

    By customizable behavior it means the implementation provided by different Derived Classes, i.e the classes which will derive from your Interface.

    Consider this:

    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
    

    So, in above example even though pMachine points to different concrete implementations (read: derived classes), the output is same irrespective of chosen implementation/derived class. That is, the customizable behavior of Machine A and Machine B is not coming in-effect or not honored. So, by having non virtual IMachine::ProcessJob(), the interface IMachine has separated/ignored/suppressed the way in which the Job will get processed irrespective of the type of Machine (CMachine_A or CMachine_B) which is used.

    Now consider this:

    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
    

    Here, when pMachine points to different concrete implementations (read: derived classes), the output is according to the chosen implementation/derived class. That is, the customizable behavior of Machine A and Machine B is coming in-effect or honored. So, by having virtual IMachine::ProcessOrder(), the interface IMachine has kept the option/way open in which the Order will get processed depending upon the type of Machine (CMachine_A or CMachine_B) which is used.

    In short, since the interface IMachine has kept the ProcessOrder as virtual therefore different implementation/derived class can provide customizable behavior for the function ProcessOrder.

    0 讨论(0)
提交回复
热议问题