Thinking about a common problem in interface inheritance when designing the DirectUI interface library (this interface library is now open-source and can be downloaded here) architecture, I encountered an interface inheritance problem, at that time, there was no good solution, but I was always worried. Now I want to rethink about it. The level of DirectUI controls is roughly as follows: among them, class names starting with I are interfaces: IObject indicates the basic interface of the framework and requires implementation of functions similar to IUnknown in COM, IControl indicates the basic interface of the control. All controls are inherited from this interface. IControlContainer indicates the basic interface of the Container Control, IButton indicates the basic interface of the Button class, And IPanel indicates a container control interface. Of course, the above framework is simplified, but the actual situation is much more complex than above, but this figure can help us explain the situation here. When Panel and Button are actually implemented, we will find that a large amount of code is duplicated and can be shared. Therefore, in actual implementation, our framework may become like this: that is to say, we will see cross-inheritance between interfaces and implementations. In fact, this method is used for implementation by myself, I think most people will use this method (in fact, WPF also uses this method ). The disadvantage of this method is obvious. The interface contains the implementation, which basically makes the interface lose its role, which is fatal in component programming, for example, in C ++, I can encapsulate it as a DLL and expose the interface to the outside in a way similar to COM, currently, this method cannot be used (only export classes can be used ). So how can we implement code reuse both based on interface programming and implementation? This is actually a syntactic sugar, that is, how to meet both the C ++ syntax and our needs. Therefore, we came up with the following implementation method: Our implementation method is based on the C ++ template, in general, the interface we want to implement is passed to the bottom layer of the inheritance class system through template parameters. The code for this method is roughly as follows: class IObject {}; class IControl: public IObject {}; class IButton: public IControl {}; template <typename TBase> class CObjectImpl: public TBase {}; template <typename TBase> class CControlImpl: public TBase {}; template <typename T, typename TBase> class CButtonImpl: public TBase {}; class CButton: public CButtonImpl <CButton, I Button >{}; this method basically meets our above requirements, both code reuse and interface-based programming, but have you found that it has a fatal drawback, this disadvantage is the code expansion caused by the C ++ template. Will the code expansion caused by the C ++ template be analyzed. That is to say, the above design will lead to a duplicate code for each control inheritance class, that is, CControlImpl <IButton> and CControlImpl <IPanel> are different class instances, therefore, they generate 2 points of code. You may think this is nothing, but think about the control inheritance class may have dozens or even hundreds, and the final executable file will be much larger. Is there any other way to implement it? It can be programmed based on interfaces and code reuse without code expansion. Therefore, we thought of the following implementation method: This method is the most primitive method. In fact, it is to separate the Interface System and the Implementation System separately, then it is inherited and combined in the final class (Button and Panel. Of course, this method also has a disadvantage, that is, we need to do more work, because we need to implement the interface (IButton) in the final class (Button ), during implementation, we need to forward all methods to the implementation class (CButtonImpl ). Finally, Let's sum up the above three methods: the first method to implement mixed inheritance with interfaces is the simplest and easiest to understand. The disadvantage is that it cannot be completely Programming Based on interfaces; the second method based on templates is hard to understand, and its implementation is relatively simple. Its disadvantage is code expansion. The third method based on multiple inheritance is also easy to understand. The disadvantage is that we need to do more work.