COM接口与抽象类

来源:互联网 发布:淘宝网开店怎么开手机 编辑:程序博客网 时间:2024/06/06 00:20

写给初学者,转载请注明出处:

yanzhong.lee

lyzaily@126.com

<<com技术内幕>>一书上说,COM的接口定义了一个内存结构,至于接口中的函数名无关紧要,这个是什么意思呢?在该书中是用C++类来实现组件的,用C++的纯抽象类来实现接口的,并不是说只有C++的抽象类可以实现接口,只有C++的非抽象类可以实现组件;只是用C++语言来实现组件比用例如过程性的C语言简单得多,自然简单何乐而不为呢!其实现实中的BREW就是用C实现的COM组件。

C++中的抽象类声明一中内存结构,而这中内存结构也是COM所要求的,真实巧合的天衣无缝,例如下面的一个抽象基类:

class CBase{
public:
 virtual int func(int param) = 0;
 virtual void func2() = 0;
 virtual void func3() = 0;
private:
  
};
在该C++抽象基类里面,定义了一种内存结构,就是在该内存的第一个地址处事函数是func,第二个地址处是func2,内存的第三个地址处是func3;要说明的是这个抽象类不能导致编译器为其分配空间,只是定义了一种内存分配的结构类型,在实例化该抽象类的子类实例化时才分配这样的内存结构。

最重要的一点就是,该抽象类定义的内存接口,与函数名称无关是什么没有任何关系,其实你也可以用如下的抽象类来定义同上一样的内存结构类型:

class CBaseEx{
public:
 virtual int funcEx(int param) = 0;
 virtual void funcEx2() = 0;
 virtual void funcEx3() = 0;
private:
  
};

抽象类中的函数名只不过就是一种内存占位符而已,用什么都可以。这一点可以由如下的例子作为证据:

#include "stdafx.h"
#include <iostream>
using namespace std;

class CBase{
public:
 virtual int func(int param) = 0;
 virtual void func2() = 0;
 virtual void func3() = 0;
private:
  
};

class CTestA:public CBase{
public:
 CTestA();
 ~CTestA();
 virtual int func(int param);
 virtual void func2();
 virtual void func3();
private:
 int m_value;
};
int CTestA::func(int param)
{
 cout<<"func"<<endl;
 m_value += param;
 this;
 return 0;
}
void CTestA::func2()
{
 cout<<"func2"<<endl;
}
void CTestA::func3()
{
 cout<<"func3"<<endl;
}

CTestA::CTestA()
{
 m_value = 0;
}
CTestA::~CTestA()
{
}


class CBaseEx{
public:
 virtual int funcEx(int param) = 0;
 virtual void funcEx2() = 0;
 virtual void funcEx3() = 0;
private:
  
};


class CTestB:public CBaseEx{
public:
 CTestB();
 ~CTestB();
 virtual int funcEx(int param);
 virtual void funcEx2();
 virtual void funcEx3();
private:
 int m_valueb;
};

int CTestB::funcEx(int param)
{
 cout<<"funcEx"<<endl;
 m_valueb += param;
 this;
 return 0;
}

void CTestB::funcEx2()
{
 cout<<"funcEx2"<<endl;
}
void CTestB::funcEx3()
{
 cout<<"funcEx3"<<endl;
}

CTestB::CTestB()
{
 m_valueb = 0;
}
CTestB::~CTestB()
{
}


int _tmain(int argc, _TCHAR* argv[])
{

 CBase* ptr = new CTestA(); //(1)
 ptr->func(1); //发出调用抽象类定义的内存结构中的第一个函数指令
 ptr->func2(); //发出调用抽象类定义的内存结构中的第二个函数指令
 ptr->func3(); //发出调用抽象类定义的内存结构中的第三个函数指令
 ptr = (CBase*)(new CTestB()); //(2)
 ptr->func(2);//发出调用抽象类定义的内存结构中的第一个函数指令
 ptr->func2();//发出调用抽象类定义的内存结构中的第二个函数指令
 ptr->func3();//发出调用抽象类定义的内存结构中的第三个函数指令

 return 0;
}
该函数的执行结果如如下:

func

func2

func3

funcEx

funcEx2

funcEx3

这就充分说明了抽象类中的函数只是个占位符,具体执行的是什么函数要看类的具体实现,之所以红色标志的第二句能够成功的调用并不是自己子类的实例函数,原因就是抽象类定义的只是一种内存结构,与函数名称无关,如果两种不同的类但是具有相同的内存结构,就可以用一个抽象类函数调用另外一个完全不相关的子类对象的实例函数。

COM接口中所说的内存结构所包含的深层意义也就在于此。COM接口只是定义了只用内存结构,通过这样的内存结构就可以保证客户只用接口中定义的函数来调用组件中的函数实现,即使组件在实现时使用了和接口不同的函数名,只要组件完全遵从接口的定义,就不会出问题。

其实抽象类中的函数名已经没有任何意思,其实就是内存地址的一种别名,如func就是代表内存中的第一个函数,func2就是代表内存中的第二个函数,依次类推。

 转载自 : http://blog.163.com/lyzaily@126/blog/static/424388372010027103050464/
0 0
原创粉丝点击