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通过分层的方式实现COM对象的不同特性,每个层次处理COM对象的特定方面。 **3.1 基础类:CComObjectRootEx** 这是最基础的类,它提供了基本的功能,如引用计数和线程安全。CComObjectRootEx是一个抽象基类,不...
Atl71压缩包包含了关于Microsoft ATL (Active Template Library) 的7.1版本的相关资源,这是一个在C++编程中广泛使用的库。ATL是微软提供的一种轻量级的COM(Component Object Model)编程框架,它使得开发者能够更...
《C++ Primer》是一本很好的入门书籍,它涵盖了C++的基础知识,如继承、重载、多态、多重继承、虚函数、纯虚函数和模板。理解这些概念对于后续学习COM至关重要,因为COM的实现很大程度上依赖于C++的特性,特别是接口...
- **ATL框架**:深入学习ATL模板类,如CComObject、CComObjectStack和CComCoClass等,以及如何利用它们简化COM组件的开发。 - **COM线程模型**:了解单线程、多线程自由调度和Apartment Threading等线程模型,以及...
3. 探索Atl:了解COM和Atl的基本原理,学习如何使用Atl模板来创建COM组件。 4. 实践项目:参与或创建实际项目,将所学知识应用于实践中,提升编程技能和问题解决能力。 5. 不断更新:随着技术的发展,定期学习新的...
- **WTL**:虽然提供了强大的功能,但其实现方式更为简洁,使得学习过程相对轻松。 **3. 自定义能力** - **MFC**:自定义能力相对较弱。 - **WTL**:提供了更多的灵活性,便于开发者进行深度定制。 #### 三、WTL...
通过研究这个"templateinterface_src",开发者可以深入理解ATL模板接口的工作原理,学习如何创建和使用COM组件,以及如何管理项目文件和配置。这对于任何想要在Windows平台上开发高效、轻量级组件的C++程序员来说都...
4. **ATL技术**:ATL是微软为优化COM编程而设计的模板库,它提供了轻量级、高效的COM对象实现方式。ATL通常用于创建小型、高性能的COM组件,书中将教授如何使用ATL创建COM服务器和客户端,并进行组件之间的通信。 5...
首先,书中详细介绍了C++的基础知识,包括类、对象、继承、多态、模板等核心概念。这些是理解C++面向对象编程的基础,也是进一步学习MFC和其他高级主题的前提。作者会深入讲解如何利用C++的特性来实现高效、可维护的...
"quanxianguanli_ATL.cpp"和"Project1_ATL.cpp"可能涉及Active Template Library(ATL),这是一个用于创建COM组件的C++模板库,可以帮助开发者快速创建轻量级、高性能的COM对象,用于实现客户端与服务器之间的通信...
2. 定义接口和实现:在ATL项目中,通过接口定义语言(IDL)文件定义COM接口,然后在C++类中实现这些接口。 3. 注册和使用COM组件:注册COM组件后,其他应用程序可以通过COM接口调用组件提供的服务。 五、调试与...
3. **模板和泛型编程**:了解如何使用模板来实现通用的代码,以及STL(Standard Template Library)容器、算法和迭代器的使用。 4. **内存管理**:理解动态内存分配和释放,避免内存泄漏问题。 5. **MFC和ATL的使用*...
然而,随着时间的推移,我们开始意识到,面向对象编程实际上是对数据私有化的一种更高级的实现方式。在C++中,通过类将数据封装起来,从而实现对数据的隐藏,提高了代码的灵活性和安全性。理解了这一点,也就掌握了...
此外,VC++6.0还支持ATL(Active Template Library),这是用于创建COM组件的模板库,对于Windows系统中的组件化编程至关重要。 以下是通过"VC++提高教程"可能涵盖的一些核心知识点: 1. **面向对象编程**:学习...
1. **C++语言**:VC6.0支持标准C++,包括类、对象、继承、多态、模板等面向对象特性,同时也支持STL(Standard Template Library),如容器、算法、迭代器等。 2. **MFC**:MFC是微软为Windows平台提供的C++类库,...
再者,继承和多态是C++中实现代码复用和模块化设计的关键,了解虚函数和纯虚函数的用法对理解多态性至关重要。 二、Visual C++6.0 IDE Visual C++6.0是微软推出的经典集成开发环境,它提供了丰富的代码编辑、调试和...
此外,对于初学者,杂志可能会介绍C++语法基础,如面向对象编程概念、模板、构造函数与析构函数、继承和多态等。对于有经验的开发者,可能涵盖更高级的主题,如模板元编程、C++11及后续标准的新特性,甚至是C++模块...
STL为C++编程提供了强大的数据结构和算法支持,通过模板机制实现了高度的通用性和效率。 5. **C++标准库**:除了STL,C++标准库还包括iostream(输入/输出流)、string(字符串处理)、locale(本地化)、智能指针...
《C++到VC++精彩100例(新版)》是一部专为编程爱好者和学习者设计的实践教程,旨在帮助读者从C++的基础过渡到使用...每例的实现将帮助你逐步提升编程能力,最终能够独立解决复杂问题,开发出高效、稳定的软件应用。