4

インターフェイスについて読むたびに、データ メンバーや実装がまったくないことが言及されています。

しかし、インターフェイスを持つコードを見ると、両方があります。

class IInterface
{
public:
    IInterface(){}
    virtual ~IInterface(){}
    int getInt(){ return m_int; }
    virtual void Boo() = 0;
    int m_int;
};

class cInterface : public IInterface
{
public:
    virtual void    Boo()
                    {
                        printf( "defined in .cpp for readability\n" );
                    };
};

class cFoo : public cInterface
{
};

(ほとんど) ソース ファイルでそれらを見ることはなく、ヘッダーだけです。

この用語はどのくらい厳密に使用されていますか? また、上記がインターフェースでない場合、どのように呼ばれますか?

IInterface* として使用する場合、cInterface/cFoo の使用法を反映していますか?

...
cFoo foo;
IInterface* object = &foo;
object->Boo();
...
4

3 に答える 3

6

C++ の言語定義にはインターフェイス型の正式な定義がなく、純粋な抽象クラスの記述を強制する方法がありません。ただし、この概念は確かにソフトウェア エンジニアリングに存在し、非常に長い道のりを歩んできました。Corba と COM は標準的な例です。一般的な手法は「インターフェイス ベースのプログラミング」と呼ばれます。もう1つの人気レーベルは「デザイン・バイ・コントラクト」。一部の C++ コンパイラには、MSVC の __interface など、それらをサポートするための言語拡張機能があります。それは他のすべての点で依然として単純なクラスであり、コンパイラは純粋さを強制するだけです。

具体的な例の 1 つは、インターフェイスを使用して、別のランタイム環境に実際に存在するオブジェクトのプロキシの定義として機能することです。地球の裏側にある機械のように。インターフェイスのローカル実装であるプロキシには、ワイヤ上で引数値を送信するメソッドがあります。ワイヤのもう一方の端には、実際のメソッドを含むスタブがあります。オブジェクトが実際にローカルで作成されている場合、クライアント コードを変更する必要がないという大きな利点があり、同じインターフェイスを引き続き使用します。つまり、実装は目に見えず、コードには影響しません。あなたが示した例は、このシナリオでは正しく動作しません。リモート オブジェクトは m_int メンバーの正しい値を持ちません。これはインターフェースではなく、単なる抽象クラスです。

インターフェイスは、多重継承を実装していない言語では特に重要です。MIはダイヤモンドの問題で難しい。しかし、これは実装の継承の問題です。複数のインターフェイスを継承しても問題はありません。このような言語が対処しなければならない唯一の小さな問題は、2 つ以上の継承されたインターフェイスが同じ名前とシグネチャを持つメソッドを持つ場合のあいまいさです。しかし、これは、実装されている特定のインターフェイス メソッドを指定する方法を言語に与えることで簡単に解決できます。C# の「明示的なインターフェイスの実装」構文と同様です。Javaが何をするかわからない。

実用的で面倒なもう 1 つの側面は、「契約による設計」という角度からの設計ツールであるということです。多くの開発者が参加する大規模なプロジェクトに取り組む場合、多くのインターフェイスが必要になる傾向があります。建築家が発する「これが私たちのすべきこと」を取り入れています。しかし、特にプロジェクトの初期には、「これが私がしたことです」というものはありません。本当のバグは実装のバグであり、めったにインターフェースのバグではありません。実際に複数のプログラマーを同時に作業させるための優れたツールです。しかし、プロジェクトのサウンドとロックインの基盤を手に入れて、その上に構築できるようにすることは大きな問題です。Bjarneのやり方ではありません。

于 2012-08-11T21:17:15.743 に答える
2

C++ では、この用語の厳密な定義はありません。一般に、ほとんどが抽象的なクラス、つまり、あらゆる種類の実装ではなく、相互作用のためのプロトコルを定義するクラスを意味するために大まかに使用されます。これは言語に組み込まれた概念ではないため、人々は定義についてあまり厳密ではなく、データが「インターフェース」に忍び込むことがあります。

ただし、一部のプログラミング言語やシステム (Java が代表的な例) では、これは言語機能であり、非常に正式な意味を持ちます。これらの環境では、正確な意味はもちろん環境固有ですが、一般的には上記で説明したものとほぼ同じです。Java では、インターフェイスは、純粋仮想関数とコンパイル時の定数データ メンバーだけを持つ一種のクラスです。Java では、クラスは他の 1 つのクラスのみを拡張できますが、クラスは任意の数のインターフェイスを実装できます。

于 2012-08-11T20:43:26.843 に答える
0

簡単に言えば、「インターフェース」はメソッドやデータ (具体的または抽象的) を参照するために使用できます (例: virtual)。「インターフェース」のより基本的な定義は、実装がアクセスできるものを参照するためによく使用されます (たとえば、パブリックなメソッドはパブリック インターフェースの一部です)。

Ernest が指摘したように、ある時点であなたが期待していた定義は Java の定義であり、Java の定義は非常に具体的なものを意味するため、大きく異なります。Java のインターフェイスの表現/定義は、C++ の純粋な抽象クラスに似ています。

そのため、「インターフェイス」は C++ の純粋な抽象クラスと同等ではありません。これは、オブジェクトの宣言されたメソッド (仮想かどうかに関係なく) や基本クラス (ただし、これらのメソッドの定義)。私は、宣言された型定義と定数でさえ、オブジェクトのインターフェースの一部として資格を得ることができます(特にテンプレートメタプログラミングで)。一部の人々の定義では、それは遠すぎるかもしれないと思いますが(実際、インターフェイスはC++で厳密に定義されていません-そのため、ある人の定義は、頻繁に訪れた水飲み場によって異なる場合があります)。

于 2012-08-11T22:08:01.717 に答える