重複の可能性:
C++ でインターフェイスを宣言するにはどうすればよいですか?
これは C++ に関する一般的な質問です。ご存じのとおり、Java や C# とは異なり、C++ では とinterface
の間に明確な区別はありません。C++で an の代わりに anabstract class
を使用する方が望ましいのはいつですか? いくつか例を挙げていただけますか?interface
abstract class
重複の可能性:
C++ でインターフェイスを宣言するにはどうすればよいですか?
これは C++ に関する一般的な質問です。ご存じのとおり、Java や C# とは異なり、C++ では とinterface
の間に明確な区別はありません。C++で an の代わりに anabstract class
を使用する方が望ましいのはいつですか? いくつか例を挙げていただけますか?interface
abstract class
インターフェイスとは、純粋な仮想メソッドのみを持つ(つまり、コードのない) C++ クラスを意味し、代わりに抽象クラスとは、オーバーライド可能な仮想メソッドといくつかのコードを持つ C++ クラスを意味しますが、少なくとも 1 つの純粋仮想メソッドを意味します。これにより、クラスがインスタンス化できなくなります。例えば:
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-tablesへのポインター、つまり一連の関数ポインターへのポインター) のみをエクスポートします。これは、たとえば、C++ で COM コンポーネントをビルドして Visual Basic で使用する、または C で COM コンポーネントをビルドして C++ で使用する、または Visual C++ で COM コンポーネントをビルドすることを可能にするABI (アプリケーション バイナリ インターフェイス)を定義するのに役立ちます。バージョン X を使用し、Visual C++ バージョン Y で使用します。つまり、インターフェイスを使用すると、クライアント コードとサーバー コードの間の分離が大きくなります。
さらに、(純粋な C DLL ではなく) C++ オブジェクト指向インターフェイスを使用して DLL をビルドする場合は、この記事で説明されているように、C++ クラスではなくインターフェイスをエクスポートする(「成熟したアプローチ」) ことをお勧めします (これは基本的には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
};
interface
主にJavaによって普及しました。
以下は、 の性質interface
とそれに相当する C++ です。
interface
本体のない抽象メソッドのみを含めることができます。C++ に相当するものは純粋なvirtual
メソッドですが、本体を持つことができる/できないinterface
static final
データ メンバーのみを含めることができます。C++ に相当するのはstatic const
、コンパイル時の定数であるデータ メンバーです。interface
値を使用できます。Javaは 1 つしか継承できない
ため、この機能が必要です。
C++ は、必要に応じてキーワードを使用して、多重継承をすぐにサポートしますimplement
class
class
class
virtual
ポイント 3 のため、interface
概念は C++ で正式に導入されることはありませんでした。それでも、それを行う柔軟性を持つことができます。
これに加えて、このトピックに関するBjarne のFAQを参照できます。
抽象クラスは、共通の実装が必要な場合に使用されます。インターフェイスは、プログラムの一部も準拠しなければならない契約を指定したいだけの場合です。インターフェイスを実装することにより、特定のメソッドを実装することが保証されます。抽象クラスを拡張することにより、その実装の一部を継承しています。したがって、インターフェイスは、メソッドが実装されていない単なる抽象クラスです (すべて純粋仮想です)。
Pure Virtual Functions は、主に以下を定義するために使用されます。
a) 抽象クラス
これらは、それらから派生させて純粋仮想関数を実装する必要がある基本クラスです。
b) インターフェース
これらは、すべての関数が純粋な仮想である「空の」クラスであるため、すべての関数を派生させてから実装する必要があります。
純粋仮想関数は、実際には基本クラスに実装がなく、派生クラスに実装する必要がある関数です。
メンバーをインターフェースに入れないでください。言い回しは正しいですが。インターフェイスを「削除」しないでください。
class IInterface()
{
Public:
Virtual ~IInterface(){};
…
}
Class ClassImpl : public IInterface
{
…
}
Int main()
{
IInterface* pInterface = new ClassImpl();
…
delete pInterface; // Wrong in OO Programming, correct in C++.
}