c++虚関数、インタフェース、抽象クラス

3580 ワード

c++の抽象クラスはインタフェースとして、イベントコールバックなどのメカニズムを実現することができる.
インタフェース実装ファイル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して新しいソフトウェアを出すことができ、さらにソフトウェアの多重化の目的を達成することができる.