• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:__interfaceに定義するメソッドについて教えてください!)

interfaceに定義するメソッドの隠蔽方法

このQ&Aのポイント
  • interfaceに定義するメソッドについて教えてください。
  • 描画エンジンであるengine.dll内で、アプリから呼ばれないメソッドをインターフェイスに定義する方法を教えてください。
  • 具体的には、Drawメソッドをアプリから非公開にする方法を知りたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • gentoo314
  • ベストアンサー率41% (15/36)
回答No.2

COMの考え方を参考にするといいと思います。 サンプルを書いてみましたので読んでみてください。 ■ アプリ用ヘッダ #define __interface struct __interface IShape { virtual bool SetPos( int x, int y ) = 0; }; __interface IRender { virtual bool DrawShape( IShape* pShape ) = 0; }; enum { TYPE_SHAPE, TYPE_POLYGON, }; void CreateObject(int typeID, void** ppObj); ■アプリ実装 main() { IShape* pShape = 0; IRender* pPolygon = 0; CreateObject( TYPE_SHPAE, &pShape); CreateObject( TYPE_POLYGON, &pPolygon); pShape->SetPos(100, 100); pRender->DrawShape( pShape ); delete pRender; delete pShape; } ■engine.dll インターフェースの実装 // engine.dll の実装個所 class CShape : public IShape { public: // interface 実装 bool SetPos( int x, int y ); public: // CShape 公開メソッド bool Draw( HDC hDC ); }; class CPolygon : public IRender { public: // interface 実装 bool DrawShape( IShape* pShape ) { ((CShape*)pShape)->Draw( m_hDC ); } public: // CPolygon 公開メソッド protected: HDC m_hDC; }; ■オブジェクト生成関数 void CreateObject(int typeID, void** ppObj) { switch( type ID) { case TYPE_SHAPE: *ppObj = new CShape; break; case TYPE_POLYGON: *ppObj = new CPolygon; break; } }

orfenok
質問者

お礼

ご回答頂きありがとうございます! >((CShape*)pShape)->Draw( m_hDC ); なるほど!エンジンが生成を担うことで(CreateObjectメソッド)、エンジン内部では生成した型へのキャスト(dynamic_cast)が可能ということですね! これなら呼ばれないメソッドも隠蔽でき、HDC型も知られずに済みそうです。大変貴重なご助言感謝致します。

その他の回答 (1)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.1

言語がC++か、C#かC++マネージかなにかわかりませんが、 C++ということで話を進めます。 C++であれば、一番楽なのは、インターフェイスを使用せず、 抽象化クラスを使用して、Drawメソッドをprivateメソッドに指定し Renderクラスを IShapeインターフェイスのフレンドにすれば良いでしょう。 インテリセンスなどからはメソッドが消えないかも知れませんが、 アクセスは制限されるので呼び出そうとすればコンパイルエラーになります。 本来、__interfanceの識別子は動作がコンパイラに依存するものなので あまり、使わない方が良いような気がします。 リファクタリングすれば、 もっとスマートになると思いますが、 質問者さんのコードを変えて C++で書くならこんな感じでしょうか。 //抽象クラス(Interface) class IShape{ public:  friend class CRender;  virtual void SetPos(int x, int y) = 0; private:  virtual void Draw() = 0; }; class CPolygon : public IShape { public:  CPolygon(){}  ~CPolygon(){}  void SetPos(int x, int y){ m_x = x; m_y = y;}; private:  void Draw(){ printf( "x:%d y:%d", m_x, m_y ); };  int m_x, m_y; }; class CRender { public:  CRender(){}  ~CRender(){}  bool Draw(IShape*Drawer){   Drawer->Draw();   return true;  } }; int main( void ) { // IShape S;//抽象クラスはインスタンス化できないのでエラー  IShape *S; //インスタンス化されないのでOK  CRender R;  S = new CPolygon;//IShapeを実装であるPolygonクラスでインスタンス化する  S->SetPos( 100, 200 );//publicなので呼び出しが可能 // S->Draw();//privateのためクラス外からはアクセスできないのでエラー  R.Draw(S);//RenderクラスはIShapeとpublicフレンドなので内部で呼び出しが可能  delete S;  return 0; } ※全角スペースは半角かタブに変換してください

orfenok
質問者

お礼

早速のご回答ありがとうございます!※ご察し頂いた通り言語はC++になります。 >本来、__interfanceの識別子は動作がコンパイラに依存するものなので クロスプラットフォームも視野に入れていますのでご指摘感謝致します! >Renderクラスを IShapeインターフェイスのフレンドにすれば良いでしょう。 なるほど。勉強になります! また、記載不足で大変申し訳ございませんが、実際にはDrawの引数となるHDCをヘッダーに書きたくないという意図もあります。 // Shapeインターフェイス[公開ヘッダー] class IShape { public:  ~IShape(){}  virtual bool SetPos(int x, int y) = 0;  virtual bool Draw(HDC hDC) = 0; // ★HDCを引数にとります。 }; // 描画インターフェイス[公開ヘッダー] class IRender { public:  ~IRender(){}  virtual bool DrawShape( IShape* pShape ) = 0; }; // 描画クラス[非公開ヘッダー] #include <windows.h> class CWinRender : public IRender {  HDC m_hDC; public:  virtual bool DrawShape( IShape* pShape ){   pShape->Draw( m_hDC ); // HDCメンバーを渡す  } }; // アプリ #include <IShape.h> #include <IRender.h> Update(IRender* pRender, IShape* pShape ){  pRender->DrawShape( pShape ); } CWinRender以外のコードはHDC(windows.h)をインクルードしていないので、Linuxなどでもビルドできるという意図があります。

関連するQ&A

専門家に質問してみよう