ATL的使用办法

ATL的使用办法 ATL使用方法#includeiostream#includeatlbase.h#includeatlwin.htemplateclassTclassEdoyun{public:voidshow(){T*pstatic_castT*(this);p-Name();}public:voidName(){std::coutEdoyunstd::endl;}// 不是虚函数};classSub:publicEdoyunSub{public:voidName(){std::coutSubstd::endl;}};classSub2:publicEdoyunSub2{};intmain(){Sub sub1;Sub2 sub2;sub1.Name();sub2.Name();}这段代码是CRTP奇异递归模板模式的经典示例涉及以下几个核心知识点1. CRTPCuriously Recurring Template Pattern定义子类继承自以自己为模板参数的基类。classSub:publicEdoyunSub{// Sub 继承 EdoyunSub把自己当模板参数这是 C 模板元编程的经典设计模式ATL/WTL、Boost 里大量使用。2. 静态多态编译期多态基类里通过static_cast把this强转子类指针在编译期就确定调用哪个函数不需要虚函数voidshow(){T*pstatic_castT*(this);// 安全的向下转型p-Name();// 编译期决定调用子类还是基类的 Name()}和动态多态虚函数对比CRTP 静态多态虚函数动态多态决议时机编译期运行期性能开销无直接调用虚表指针、虚表查找用法子类继承BaseSub基类写 virtual子类 override灵活性编译时确定运行时可动态切换3. 名字隐藏Name Hiding子类的Name()不是重写没有 virtual而是隐藏了基类的同名函数Sub sub1;sub1.Name();// 调用 Sub::Name()输出 Sub —— 子类隐藏了基类版本Sub2 sub2;sub2.Name();// Sub2 没定义 Name()调用继承的 Edoyun::Name()输出 Edoyun注意如果是虚函数叫「重写override」不是虚函数就叫「隐藏hiding」。4.static_cast安全向下转型为什么static_castT*(this)是安全的因为this指向的对象实际就是T类型子类对象只是当前作用域是基类视角。编译器在编译期就能确认这个转型合法比dynamic_cast快不需要 RTTI。运行结果Sub ← sub1 自己有 Name()隐藏了基类版本 Edoyun ← Sub2 没有 Name()用继承来的基类版本补充CRTP 的常见用途静态多态给子类自动添加功能如计数器、单例、对象池实现 fluent interface / 链式调用Mixin 混合类给类叠加能力ATL/WTL 窗口类封装就是你头文件对应的场景简单说想有多态的效果但又不想承担虚函数的开销 → 用 CRTP。