`
narwhal
  • 浏览: 6693 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类
最新评论

ATL模板中实现多态的方式

阅读更多
ATL-style 模板
即使你能够毫不费力地阅读C++的模板类代码,仍然有两件事可能会使你有些头晕,以下面这个类的定义为例:
class  CMyWnd : public CWindowImpl<CMyWnd>
{
    ...
};
 
这样作是合法的,因为C++的语法解释说即使CMyWnd类只是被部分定义,类名CMyWnd已经被列入递归继承列表,是可以使用的。将类名作为模板类的参数是因为ATL要做另一件诡秘的事情,那就是编译期间的虚函数调用机制。

如果你想要了解它是如何工作地,请看下面的例子:
template <class T>
class B1
{
public: 
    void SayHi() 
    {
        T* pT = static_cast<T*>(this);   // HUH?? 我将在下面解释
 
        pT->PrintClassName();
    }
protected:
    void PrintClassName() { cout << "This is B1"; }
};
 
class D1 : public B1<D1>
{
    // No overridden functions at all
};
 
class D2 : public B1<D2>
{
protected:
    void PrintClassName() { cout << "This is D2"; }
};
 
main()
{
    D1 d1;
    D2 d2;
 
    d1.SayHi();    // prints "This is B1"
    d2.SayHi();    // prints "This is D2"
}

这句代码static_cast<T*>(this) 就是窍门所在。它根据函数调用时的特殊处理将指向B1类型的指针this指派为D1或D2类型的指针,因为模板代码是在编译其间生成的,所以只要编译器生成正确的继承列表,这样指派就是安全的。(如果你写成:
class D3 : public B1<D2>
就会有麻烦) 之所以安全是因为this对象只可能是指向D1或D2(在某些情况下)类型的对象,不会是其他的东西。注意这很像C++的多态性(polymorphism),只是SayHi()方法不是虚函数。

要解释这是如何工作的,首先看对每个SayHi()函数的调用,在第一个函数调用,对象B1被指派为D1,所以代码被解释成:
void B1<D1>::SayHi()
{
    D1* pT = static_cast<D1*>(this);
 
    pT->PrintClassName();
}

由于D1没有重载PrintClassName(),所以查看基类B1,B1有PrintClassName(),所以B1的PrintClassName()被调用。

现在看第二个函数调用SayHi(),这一次对象被指派为D2类型,SayHi()被解释成:
void B1<D2>::SayHi()
{
    D2* pT = static_cast<D2*>(this);
 
    pT->PrintClassName();
}

这一次,D2含有PrintClassName()方法,所以D2的PrintClassName()方法被调用。

这种技术的有利之处在于:

不需要使用指向对象的指针。
节省内存,因为不需要虚函数表。
因为没有虚函数表所以不会发生在运行时调用空指针指向的虚函数。
所有的函数调用在编译时确定(译者加:区别于C++的虚函数机制使用的动态编连),有利于编译程序对代码的优化。
节省虚函数表在这个例子中看起来无足轻重(每个虚函数只有4个字节),但是设想一下如果有15个基类,每个类含有20个方法,加起来就相当可观了。
分享到:
评论

相关推荐

    ATL 揭秘之“对象创建”篇

    ATL通过分层的方式实现COM对象的不同特性,每个层次处理COM对象的特定方面。 **3.1 基础类:CComObjectRootEx** 这是最基础的类,它提供了基本的功能,如引用计数和线程安全。CComObjectRootEx是一个抽象基类,不...

    atl71压缩包

    Atl71压缩包包含了关于Microsoft ATL (Active Template Library) 的7.1版本的相关资源,这是一个在C++编程中广泛使用的库。ATL是微软提供的一种轻量级的COM(Component Object Model)编程框架,它使得开发者能够更...

    我的COM和ATL的学习.docx

    《C++ Primer》是一本很好的入门书籍,它涵盖了C++的基础知识,如继承、重载、多态、多重继承、虚函数、纯虚函数和模板。理解这些概念对于后续学习COM至关重要,因为COM的实现很大程度上依赖于C++的特性,特别是接口...

    COM学习原码

    - **ATL框架**:深入学习ATL模板类,如CComObject、CComObjectStack和CComCoClass等,以及如何利用它们简化COM组件的开发。 - **COM线程模型**:了解单线程、多线程自由调度和Apartment Threading等线程模型,以及...

    计算机软件开发

    3. 探索Atl:了解COM和Atl的基本原理,学习如何使用Atl模板来创建COM组件。 4. 实践项目:参与或创建实际项目,将所学知识应用于实践中,提升编程技能和问题解决能力。 5. 不断更新:随着技术的发展,定期学习新的...

    WTL for MFC Programmer

    - **WTL**:虽然提供了强大的功能,但其实现方式更为简洁,使得学习过程相对轻松。 **3. 自定义能力** - **MFC**:自定义能力相对较弱。 - **WTL**:提供了更多的灵活性,便于开发者进行深度定制。 #### 三、WTL...

    ATLVC源代码:templateinterface_src

    通过研究这个"templateinterface_src",开发者可以深入理解ATL模板接口的工作原理,学习如何创建和使用COM组件,以及如何管理项目文件和配置。这对于任何想要在Windows平台上开发高效、轻量级组件的C++程序员来说都...

    Visual C++高级编程技术与实例

    4. **ATL技术**:ATL是微软为优化COM编程而设计的模板库,它提供了轻量级、高效的COM对象实现方式。ATL通常用于创建小型、高性能的COM组件,书中将教授如何使用ATL创建COM服务器和客户端,并进行组件之间的通信。 5...

    vc++技术内幕(第四版)

    首先,书中详细介绍了C++的基础知识,包括类、对象、继承、多态、模板等核心概念。这些是理解C++面向对象编程的基础,也是进一步学习MFC和其他高级主题的前提。作者会深入讲解如何利用C++的特性来实现高效、可维护的...

    权限管理系统 C/S模式C++ 完整程序,源代码

    "quanxianguanli_ATL.cpp"和"Project1_ATL.cpp"可能涉及Active Template Library(ATL),这是一个用于创建COM组件的C++模板库,可以帮助开发者快速创建轻量级、高性能的COM对象,用于实现客户端与服务器之间的通信...

    Visual C++ 6.0实例

    2. 定义接口和实现:在ATL项目中,通过接口定义语言(IDL)文件定义COM接口,然后在C++类中实现这些接口。 3. 注册和使用COM组件:注册COM组件后,其他应用程序可以通过COM接口调用组件提供的服务。 五、调试与...

    明日科技Visual C++源码打包下载

    3. **模板和泛型编程**:了解如何使用模板来实现通用的代码,以及STL(Standard Template Library)容器、算法和迭代器的使用。 4. **内存管理**:理解动态内存分配和释放,避免内存泄漏问题。 5. **MFC和ATL的使用*...

    简述C和C++的学习历程

    然而,随着时间的推移,我们开始意识到,面向对象编程实际上是对数据私有化的一种更高级的实现方式。在C++中,通过类将数据封装起来,从而实现对数据的隐藏,提高了代码的灵活性和安全性。理解了这一点,也就掌握了...

    vc++提高教程

    此外,VC++6.0还支持ATL(Active Template Library),这是用于创建COM组件的模板库,对于Windows系统中的组件化编程至关重要。 以下是通过"VC++提高教程"可能涵盖的一些核心知识点: 1. **面向对象编程**:学习...

    vc6.0 MSDN精简CHM版

    1. **C++语言**:VC6.0支持标准C++,包括类、对象、继承、多态、模板等面向对象特性,同时也支持STL(Standard Template Library),如容器、算法、迭代器等。 2. **MFC**:MFC是微软为Windows平台提供的C++类库,...

    Visual C++6.0技术内幕(压缩文件)

    再者,继承和多态是C++中实现代码复用和模块化设计的关键,了解虚函数和纯虚函数的用法对理解多态性至关重要。 二、Visual C++6.0 IDE Visual C++6.0是微软推出的经典集成开发环境,它提供了丰富的代码编辑、调试和...

    VC知识库电子杂志41-45期

    此外,对于初学者,杂志可能会介绍C++语法基础,如面向对象编程概念、模板、构造函数与析构函数、继承和多态等。对于有经验的开发者,可能涵盖更高级的主题,如模板元编程、C++11及后续标准的新特性,甚至是C++模块...

    VisualC++类库参考手册

    STL为C++编程提供了强大的数据结构和算法支持,通过模板机制实现了高度的通用性和效率。 5. **C++标准库**:除了STL,C++标准库还包括iostream(输入/输出流)、string(字符串处理)、locale(本地化)、智能指针...

    C++到VC++精彩100例(新版)

    《C++到VC++精彩100例(新版)》是一部专为编程爱好者和学习者设计的实践教程,旨在帮助读者从C++的基础过渡到使用...每例的实现将帮助你逐步提升编程能力,最终能够独立解决复杂问题,开发出高效、稳定的软件应用。

Global site tag (gtag.js) - Google Analytics