OOP vs macro problem

前端 未结 7 1217

I came across this problem via a colleague today. He had a design for a front end system which goes like this:

class LWindow
{
   //Interface for common meth         


        
7条回答
  •  -上瘾入骨i
    2021-01-04 13:13

    OP seems confused. Here' what to do, it is very complex but it works.

    Rule 1: Design the abstractions. If you have an "is-A" relation you must use public virtual inheritance.

    struct Window { .. };
    struct ListBox : virtual Window { .. };
    

    Rule 2: Make implementations, if you're implementing an abstraction you must use virtual inheritance. You are free to use inheritance to save on duplication.

    class WindowImpl : virtual Window { .. };
    class BasicListBoxImpl : virtual ListBox, public WindowImpl { .. };
    class FancyListBoxImpl : public BasicListBoxImpl { };
    

    Therefore you should read "virtual" to mean "isa" and other inheritance is just saving on rewriting methods.

    Rule3: Try to make sure there is only one useful function in a concrete type: the constructor. This is sometimes hard, you may need some default and some set methods to fiddle things. Once the object is set up cast away the implementation. Ideally you'd do this on construction:

    ListBox *p = new FancyListBoxImpl (.....);
    

    Notes: you are not going to call any abstract methods directly on or in an implementation so private inheritance of abstract base is just fine. Your task is exclusively to define these methods, not to use them: that's for the clients of the abstractions only. Implementations of virtual methods from the bases also might just as well be private for the same reason. Inheritance for reuse will probably be public since you might want to use these methods in the derived class or from outside of it after construction to configure your object before casting away the implementation details.

    Rule 4: There is a standard implementation for many abstractions, known as delegation which is one you were talking about:

    struct Abstract { virtual void method()=0; };
    
    struct AbstractImpl_Delegate: virtual Abstract { 
      Abstract *p;
      AbstractImpl_Delegate (Abstract *q) : p(q) {}
      void method () { p->method(); }
    };
    

    This is a cute implementation since it doesn't require you to know anything about the abstraction or how to implement it... :)

提交回复
热议问题