IUnknown中的QueryInterface的实现剖析(2)

Breakpoint1

interface IX : IUnknown  这里使用struct的默认继承,但是在VS2010中的Object Browser窗口中看到的是接口的private继承这个似乎和struct的作用相违背啊(~挺疑惑的~)。

Breakpoint2 之后的几句代码中实现接口中继承到的方法,你会发现IUnknown继承的方法并没有使用类名来区分而display则分别使用IX::和IY::来区分。

前者说明从IX和IY继承到的IUnknown方法的实现方式都是一样的(p.33)而后者则需要使用不同的是方式来表达自己。

Breakpoint3之后的代码为 QueryInterface的具体实现,在原书中使用的是纯if...else...方式,如果细心阅读会发现这段代码很长重复了很多。如果我们将if...else...改成if语句实现就很容易发现这点。再次观察修改后的代码就很容易想到是不是可以用#define来简化呢?

答案是肯定的,如下提供代码供参考:

在server.h代码中加入

// macros for QueryInterface implement
#	define	QUERY_IMPL_BEGIN()				*ppv = NULL

#		define	IDENTIFY3(tmp1,tmp2,tmp3)		\
			if(iid == IID_##tmp1##)							\
			{\
				trace("QueryInterface: Return pointer to "#tmp1".");		\
				*ppv = static_cast<##tmp1##*>(static_cast<##tmp2##*>(static_cast<##tmp3##>(this)));				\
			}\

#		define	IDENTIFY2(tmp1, tmp2)					\
			if(iid == IID_##tmp1##)							\
			{\
				trace("QueryInterface: Return pointer to "#tmp1".");		\
				*ppv = static_cast<##tmp1##*>(static_cast<##tmp2##*>(this));				\
			}\

#		define	IDENTIFY1(tmp1)			\
			if(iid == IID_##tmp1##)				\
			{\
				trace("QueryInterface: Return pointer to "#tmp1" .");	\
				*ppv = static_cast<##tmp1##*>(this);			\
			}\

#		define	IDENTIFY0()		\
			if(NULL == *ppv)			\
			{\
				trace("QueryInterface: Interface not found.");			\
				return E_NOINTERFACE;			\
			}\

#	define	QUERY_IMPL_END()		\
		reinterpret_cast<IUnknown*>(*ppv)->AddRef();	\
		return S_OK;	\

//	end defining QueryInterface implement


QueryInterface可以简化为:

HRESULT CX::QueryInterface(const IID& iid , void ** ppv)
{
	QUERY_IMPL_BEGIN();
	IDENTIFY2(IUnknown, IX);
	IDENTIFY1(IX);
	IDENTIFY1(IY);
	IDENTIFY0();
	QUERY_IMPL_END();
}


Breakpoint4

原书使用CreateInstance()函数来实现CA类的创建,我觉得这里存在漏洞。首先考虑CreateInstance 这个例程应该放在服务端还是客户端呢?如果在服务端就必须提供多个这样的函数来实现多个类的创建而且还必须暴露这个函数很明显不方便,那就放在客户端了。为了简化我这里使用auto变量来实现。

通过上面简单的实现可以简单的看出COM的工作。

留下几个问题:

可以使用dynamic_cast实现转换么?

为啥非得使用void**,void*不可以么?

如何对CreateInstance进行合理的内存管理?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值