Template usage techniques in ATL

zhaozj2021-02-16  64

1. Introduction to the base class, inheritance Implementation When designing the COM interface, it is often encountered: designed a base connection, other multiple interfaces inherit the interface. A typical example is an IUNKNOWN interface, and all COM interfaces must be inherited from the iUnknown interface, and the implementation of these interfaces is the same, we cannot write an implementation of an IUnknown interface for each COM interface. The IUNKNOWN interface is more complex, distributed in several classes (you can refer to "in-depth analysis ATL"). A more intuitive example is the implementation of the iDispatch interface, which typically requires classes that implement the IDispatch interface from iDispatchImpl. This structure is like this:

Class ATL_NO_VTABLE CBBB: PUBLIC IDISPATCHIMPL

Template Class ATL_NO_VTABLE IDSPATCHIMPL: PUBLIC T, each of the classes that need to implement the IDispatch interface only need to inherit from IdispatchImpl. Idispatchimpl's approach is actually quite simple, just introducing an implementation class. Another common situation is to separate the interface and implementation. For example, the following interface inheritance structure: interface ibase {Virtual void a () = 0;}; interface idherive1: public ibase = 0;}; interface idherive2: public ibase {Virtual Void D2 () = 0 }; IBASE, the implementation class is as follows: Class CBase: Public ibase {Virtual Void A () {...}; here, there is a class CDerive1 requires inheritance interface iderive1 and implement class CBase, if directly from two classes , Like this: class cderive1: public cbase, public iDerive1 {public: void d1 () {}}; When using CDerive1 classes, the compiler complains that the ambitions can be complained. Naturally, considering the use of virtual inheritance: interface idherive1: Virtual public ibase {Virtual Void D1 () = 0;}; Class CBase: Virtual public ibase {

PUBLIC: Virtual Void A () {...}}; class cderive1: public cbase, public iDerive1 {public: void d1 () {}}; everything looks perfect, Virtual inherits solves the ambiguous problem. However, virtual inheritance is a lot of root causes of complexity problems, it is difficult to expand and maintain. It seems that we are still only elders to add an intermediate layer. The final solution is as follows:

Template Class CBase: Public TBase {public: Virtual Void A () {...}}; class cderive1: public cbase {public: void d1 () {}}

2, in the subclass in the ATL, there is a lot of the following usage: Template Class CB {public: void fun1 () {t * pt = static_cast (this); Pt-> Fund () ; // Call the function}}; here, the subclass of CB CBD: public CB {public: void fund () {...}}; this technology is actually a bit like virtual function .

The above statement t * pt = static_cast (this) can be compiled by the template class CB has been instantiated as CB during the compilation period, and the compiler already knows that T is CD, and the CD inherits from CB Therefore, it is safe from the CB to the CD to the CD. One advantage of this method is no need for a T type object, which can directly use the THIS pointer security transformation. 2, avoid the overhead of the virtual function call, although the overhead of the virtual function It is very small, and it is almost negligible in situations in the case, but the existence of virtual functions is not conducive to the optimization of the compiler, and the Static and Inline virtual functions have problems.

转载请注明原文地址:https://www.9cbs.com/read-17519.html

New Post(0)