atl中常见的模板使用手法

原创 2004年07月09日 18:54:00

1、传入基类,继承实现
在设计com接口时,经常会遇到这样的情况:设计一个基接口,其他多个接口继承该接口。一个典型的例子是IUnknown接口,所有的com接口必须从IUnknown接口继承,而这些接口的实现都是相同的,我们不可能为每一个com接口写一个IUnknown接口的实现。IUnknown接口的实现比较复杂,分布在几个类中(可参考《深入解析atl》)。比较直观的一个例子是IDispatch接口的实现,通常需要实现IDispatch接口的类都从IDispatchImpl继承。这个结构是这样的:

class ATL_NO_VTABLE Cbbb :
 public IDispatchImpl<Ibbb, &IID_Ibbb, &LIBID_AAAALib>

template <class T, ...>
class ATL_NO_VTABLE IDispatchImpl : public T
               
这样,每个需要实现IDispatch接口的类都只需要从IDispatchImpl继承即可。
IDispatchImpl的做法其实相当简单,仅仅是引入了一个实现类而已。
另一种常见的情况是分离接口和实现。比如有以下的接口继承结构:
interface IBase
{
    virtual void A()=0;
};
interface IDerive1 : public IBase
{
    virtual void D1()=0;
};
interface IDerive2 : public IBase
{
    virtual void D2()=0;
};
IBase对应的实现类如下:
class CBase : public IBase
{
    virtual void A(){...}
};
这里假设有一个类CDerive1需要继承接口IDerive1和实现类CBase,如果直接从两个类继承,象这样:
class CDerive1 : public CBase,public IDerive1
{
public:
    void D1(){}
};
当使用CDerive1类时,编译器会抱怨模棱两可。很自然的,考虑到用虚拟继承解决:
interface IDerive1 : 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(){}
};
一切看起来都很完美,virtual继承解决了模棱两可问题。但是虚拟继承是很多产生复杂性问题的根源,难以扩展和维护.
看来我们还是只有老老实实加一个中间层吧。最终解决方案如下:

template<typename TBase>
class CBase : public TBase
{
public:
    virtual void A(){...}
};
class CDerive1 : public CBase<IDerive1>
{
public:
    void D1(){}
};

2、传入子类
在atl中,有大量的以下用法:
template<typename T>
class CB
{
public:
    void Fun1()
    {
        T* pT = static_cast<T*>(this);
        pT->FunD(); //调用T的函数
    }
};
这里传进来的是CB的子类
class CD : public CB<CD>
{
public:
    void FunD(){...}
};

这种技术实际上有点象虚函数.

以上语句T* pT = static_cast<T*>(this)之所以能编译通过是因为模板类CB在编译期间已被实例化为CB<CD>,编译器已经知道T就是CD,而CD继承自CB,所以从CB向CD转型是安全的.这种手法的一个好处是不需要一个T类型的对象,直接可以使用this指针安全转型.其2,避免了虚函数调用的开销,虽然虚函数的开销是很小的,单继承情况下几乎可以忽略不计,但是虚函数的存在不利于编译器的优化,而且static和inline虚函数也要出问题.

 

 

 

 

 

 


 

VS2012创建ATL工程及使用MFC测试COM组件

这篇文章首先介绍了如何创建一个ATL工程,并为其添加接口类和实现接口方法;然后介绍了如何利用自动化的方式调用由ATL生成的dll,即在程序中获取CLSID和IID然后创建接口实例;最后分析了在程序中C...
  • pigautumn
  • pigautumn
  • 2015年01月22日 16:23
  • 6565

【C++】C++常见面试题汇总,持续更新中...

1:指针(*)、引用(&)、解引用(*)、取地址(&)、的概念和区别 概念: 指针指向一块内存,指针保存的是内存的地址;引用是变量的别名,本质是引用该变量的地址。 解引用是取指针指向的地址的内容...
  • hero_myself
  • hero_myself
  • 2016年03月23日 13:53
  • 6253

在非MFC项目中使用CString

https://social.msdn.microsoft.com/Forums/sqlserver/zh-CN/22942bc0-1804-425a-a533-b5ed1d7ce892/mfccst...
  • az44yao
  • az44yao
  • 2015年04月18日 14:52
  • 1470

黑客大全(这个教程有现在比较常见的攻击手法)

  • 2008年10月27日 15:34
  • 2.98MB
  • 下载

假账常见手法文档经验

  • 2009年11月11日 12:20
  • 15KB
  • 下载

关于黑帽SEO的16种常见操作手法解析

黑帽SEO的操作手法可能对刚接触SEO或一直从事白帽SEO的朋友来讲有些陌生甚至是抵触,然而还是有很多人愿意冒着Google沙盒、百度沙盒,甚至被K站的风险去使用黑帽SEO,这是因为黑帽SEO能够短期...
  • okfei
  • okfei
  • 2014年05月30日 21:27
  • 1696

分针网—每日分享:H5动效的常见制作手法

众所周知,一个元素,动往往比静更吸引眼球; 一套操作界面,合适的动态交互反馈能给用户带来更好的操作体验; 一个H5运营宣传页,炫酷的...
  • dansuwei1234
  • dansuwei1234
  • 2017年05月17日 09:27
  • 394

835全讯网为你解常见的操盘手法

以前一直都不知道亚洲盘是什么,自从在835全讯网学习了,我很快的成为了一个高手,我想835全讯网的力量真的很大,有什么不懂的地方,你们都可以去835看看.下面为你分析的亚洲盘     一:正常盘 ...
  • qufuli0505
  • qufuli0505
  • 2015年05月14日 16:29
  • 9

H5动效的常见制作手法

众所周知,一个元素,动往往比静更吸引眼球; 一套操作界面,合适的动态交互反馈能给用户带来更好的操作体验; 一个H5运营宣传页,炫酷的动画特效定能助力传播和品牌打造。 近两年,小到lo...
  • laokdidiao
  • laokdidiao
  • 2016年04月16日 19:43
  • 904

最常见的的优化手法有哪些?汇总常见的SEO快速优化方式

SEO优化市场一直都是鱼龙混杂,各类优化手法层出不穷,但不论什么样的手法,都脱离不了最基础的以收录排名流量为导向的优化方式,那么在优化的过程中,最常见的的优化手法有哪些呢?首先,我们要做的是对自己的网...
  • abnmgft
  • abnmgft
  • 2014年06月26日 13:03
  • 242
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:atl中常见的模板使用手法
举报原因:
原因补充:

(最多只允许输入30个字)