1. ホーム
  2. c++

[解決済み] C++の抽象クラスとインターフェース [重複] [重複

2022-11-10 18:20:19

質問

重複の可能性があります。

C++でインターフェイスを宣言するにはどうしたらいいですか?

これはC++に関する一般的な質問です。ご存知のように、C++では interfaceabstract class は、JavaやC#とは異なり、C++では どのような場合に interface の代わりに abstract class の代わりにC++を使うのですか?いくつかの例を与えてもらえますか?

どのように解決するのですか?

私は インターフェース のみを持つ C++ クラスを意味します。 純粋な仮想 メソッド(つまりコードなし)のみで、代わりに 抽象クラス というのは、オーバーライド可能な仮想メソッドと、いくつかのコードを持つ C++ クラスを意味しますが 少なくとも一つの純粋な仮想メソッド で、そのクラスはインスタンス化できない。 例

class MyInterface
{
public:
  // Empty virtual destructor for proper cleanup
  virtual ~MyInterface() {}

  virtual void Method1() = 0;
  virtual void Method2() = 0;
};


class MyAbstractClass
{
public:
  virtual ~MyAbstractClass();

  virtual void Method1();
  virtual void Method2();
  void Method3();

  virtual void Method4() = 0; // make MyAbstractClass not instantiable
};

Windowsのプログラミングでは インターフェイス の基本です。 COM . 実際、COM コンポーネントはインターフェースのみをエクスポートします。 v-テーブル へのポインタ、すなわち、関数ポインタのセットへのポインタ) のみエクスポートします。これは ABI (Application Binary Interface) を定義するのに役立ちます。例えば、C++ で COM コンポーネントを構築して Visual Basic で使用したり、C で COM コンポーネントを構築して C++ で使用したり、Visual C++ バージョン X で COM コンポーネントを構築して Visual C++ バージョン Y で使用したりすることが可能になります。 言い換えれば、インターフェイスを使用することで、クライアントコードとサーバーコードの間の高いデカップリングが可能になります。

さらに、C++ オブジェクト指向インターフェイスで DLL を構築したい場合 (純粋な C の DLL の代わりに) は、次のようになります。 この記事 で説明されているように インターフェース (これは基本的に COM が行うことですが、COM インフラストラクチャの負担はありません) の代わりに、(成熟したアプローチです) インターフェイスをエクスポートする方がよいでしょう。

私なら インターフェイスを使用します。 を使うことになるでしょう。このインターフェイスを実装するクラスは、それ自身で何らかの具体的な動作を提供することになります。

代わりに、私は 抽象クラス を使用します。 インフラストラクチャ・コード を提供し、クライアントコードがこの抽象クラスから派生し、カスタムコードで純粋な仮想メソッドをオーバーライドし を完成させます。 この振る舞いをカスタムコードで完成させることができます。 例えば、OpenGLアプリケーションのインフラストラクチャを考えてみてください。 OpenGL を初期化し、ウィンドウ環境を設定する抽象クラスを定義し、このクラスから派生して、たとえばレンダリング処理やユーザー入力の処理などのカスタム コードを実装することができます。

// Abstract class for an OpenGL app.
// Creates rendering window, initializes OpenGL; 
// client code must derive from it 
// and implement rendering and user input.
class OpenGLApp
{
public:
  OpenGLApp();
  virtual ~OpenGLApp();
  ...

  // Run the app    
  void Run();


  // <---- This behavior must be implemented by the client ---->

  // Rendering
  virtual void Render() = 0;

  // Handle user input
  // (returns false to quit, true to continue looping)
  virtual bool HandleInput() = 0;

  // <--------------------------------------------------------->


private:
  //
  // Some infrastructure code
  //
  ... 
  void CreateRenderingWindow();
  void CreateOpenGLContext();
  void SwapBuffers();
};


class MyOpenGLDemo : public OpenGLApp
{
public:
  MyOpenGLDemo();
  virtual ~MyOpenGLDemo();

  // Rendering
  virtual void Render();  // implements rendering code

  // Handle user input
  virtual bool HandleInput(); // implements user input handling


  //  ... some other stuff
};