c++虚関数、インタフェース、抽象クラス
3580 ワード
c++の抽象クラスはインタフェースとして、イベントコールバックなどのメカニズムを実現することができる.
インタフェース実装ファイルIDemoImpl.cpp
インタフェースファイルIDemo.h
オブジェクトのクライアントはこのように呼び出すことができます
IDemoImpl.cppはdllまたはsoにコンパイルし、インタフェースファイルIDemoのみをパブリッシュする.hとバイナリの実現で、comの雛形が少しできました.
このGetInstance()は簡単すぎて、別のオブジェクトを取得するようにidを変更できれば、
例えばGetInstance(const char*uuid)では、この関数にはmsのIUnkownインタフェースのQueryInterface()の意味があります.
QueryInterfaceの様子を参考にGetInstance()を実現
新しいIDemoを変更します.h
異なる機能を分離するインタフェース定義
IDemoAdd.h
IDemoSub.h
それぞれ2つのcppファイルにCDemoAddImplクラスとCDemoSubImplクラスを用いて,Add()とSub()メソッドを実現する(略)
そして実装したcppをバイナリのdllまたはsoファイルにコンパイルし,3ヘッダファイル(IDemo.h IDemoAdd.h IDemoSub.h)とともにクライアントに公開する.
クライアント呼び出しは次のようになります.
まとめてみます.
comの基本思想は,オブジェクトインタフェース(ヘッダファイル)を公開することであるが,オブジェクトインタフェース実装の詳細(バイナリライブラリ)を隠す.これらのインタフェースの定義により、クライアントはバイナリのレベルで積み木のようにmashupして新しいソフトウェアを出すことができ、さらにソフトウェアの多重化の目的を達成することができる.
インタフェース実装ファイルIDemoImpl.cpp
#include <stdio.h>
#include "IDemo.h"
IDemo::IDemo(){}
IDemo::~IDemo(){}
class CDemoImpl : public IDemo
{
public:
CDemoImpl(){};
~CDemoImpl(){};
public:
virtual int Add(int a, int b)
{
return (a+b);
}
virtual int Sub(int a, int b)
{
return (a-b);
}
};
IDemo * GetInstance(void)
{
return new CDemoImpl();
}
インタフェースファイルIDemo.h
#ifndef _IDEMO_H_
#define _IDEMO_H_
class IDemo
{
public:
IDemo();
virtual ~IDemo();
public:
virtual int Add(int, int) = 0;
virtual int Sub(int, int) = 0;
};
IDemo * GetInstance(void);
#endif
オブジェクトのクライアントはこのように呼び出すことができます
#include "IDemo.h"
int main(void)
{
IDemo * pDemo = GetInstance();
printf("%d
", pDemo->Add(1,2));
}
IDemoImpl.cppはdllまたはsoにコンパイルし、インタフェースファイルIDemoのみをパブリッシュする.hとバイナリの実現で、comの雛形が少しできました.
このGetInstance()は簡単すぎて、別のオブジェクトを取得するようにidを変更できれば、
例えばGetInstance(const char*uuid)では、この関数にはmsのIUnkownインタフェースのQueryInterface()の意味があります.
HRESULT QueryInterface(
[in] REFIID riid,
[out] void **ppvObject
);
QueryInterfaceの様子を参考にGetInstance()を実現
void * GetInstance(const char * uuid)
{
if (!strcmp(uuid, "uuid_add")
return new CDemoAddImpl();
if (!strcmp(uuid, "uuid_sub")
return new CDemoSubImpl();
return (void *) 0;
}
新しいIDemoを変更します.h
#ifndef _IDEMO_H_
#define _IDEMO_H_
#ifdef __cplusplus
extern "C"
{
#endif
void * GetInstance(const char * uuid);
#ifdef __cplusplus
};
#endif
#endif
異なる機能を分離するインタフェース定義
IDemoAdd.h
#ifndef _IDEMO_ADD_H_
#define _IDEMO_ADD_H_
class IDemoAdd
{
public:
IDemoAdd();
virtual ~IDemoAdd();
public:
virtual int Add(int, int) = 0;
}
#endif
IDemoSub.h
#ifndef _IDEMO_SUB_H_
#define _IDEMO_SUB_H_
class IDemoSub
{
public:
IDemoSub();
virtual ~IDemoSub();
public:
virtual int Sub(int, int) = 0;
}
#endif
それぞれ2つのcppファイルにCDemoAddImplクラスとCDemoSubImplクラスを用いて,Add()とSub()メソッドを実現する(略)
そして実装したcppをバイナリのdllまたはsoファイルにコンパイルし,3ヘッダファイル(IDemo.h IDemoAdd.h IDemoSub.h)とともにクライアントに公開する.
クライアント呼び出しは次のようになります.
#include <stdio.h>
#include "IDemo.h"
#include "IDemoAdd.h"
#include "IDemoSub.h"
int main(void)
{
IDemoAdd * pAdd = GetInstance("uuid_add");
if (pAdd)
pAdd->Add(1,2);
IDemoSub * pSub = GetInstance("uuid_sub");
pSub->Sub(1,2);
return 0;
}
まとめてみます.
comの基本思想は,オブジェクトインタフェース(ヘッダファイル)を公開することであるが,オブジェクトインタフェース実装の詳細(バイナリライブラリ)を隠す.これらのインタフェースの定義により、クライアントはバイナリのレベルで積み木のようにmashupして新しいソフトウェアを出すことができ、さらにソフトウェアの多重化の目的を達成することができる.