概念 (つまり、最近 C++0x 標準から削除されたもの) は、Java などの言語のインターフェイスとどう違うのですか?
5 に答える
概念はコンパイル時のポリモーフィズムのためのものです。つまり、パラメトリック ジェネリック コードです。インターフェイスは、実行時のポリモーフィズム用です。
コンセプトを実装する際には、インターフェイスを実装する必要があります。違いは、コンセプトを実装していることを明示的に言う必要がないことです。必要なインターフェースが一致していれば問題ありません。インターフェイスの場合、必要な機能をすべて実装したとしても、それを実装しているという興奮を覚えなければなりません。
私は私の答えを明確にしようとします:)
sizeメンバー関数を持つ任意の型を受け入れるコンテナーを設計しているとします。Concept を形式化して HasSize と呼びます。もちろん、別の場所で定義する必要がありますが、これはもはや例ではありません。
template <class HasSize>
class Container
{
HasSize[10]; // just an example don't take it seriously :)
// elements MUST have size member function!
};
次に、 Containerのインスタンスを作成していて、それをmyShapesと呼んでいると想像してください。Shapeは基本クラスであり、sizeメンバー関数を定義します。Square と Circle はその子にすぎません。Shape でサイズが定義されていない場合は、エラーが発生するはずです。
Container<Shape> myShapes;
if(/* some condition*/)
myShapes.add(Square());
else
myShapes.add(Circle());
コンパイル時にHasSizeに対して Shape をチェックできることがお分かりいただけたと思いますが、実行時にチェックを行う理由はありません。myShapesの要素とは異なり、それらを操作する関数を定義できます。
void doSomething(Shape* shape)
{
if(/* shape is a Circle*/)
// cast then do something with the circle.
else if( /* shape is a Square */)
// cast then do something with the square.
}
この関数では、Circle または Square の実行時まで何が渡されるかわかりません!
これらは似たような仕事をするための 2 つのツールですが、Interface (またはあなたがそれらを何と呼んでいても) は実行時にほぼ同じ概念の仕事を行うことができますが、コンパイル時のチェックと最適化のすべての利点を失います!
概念は、テンプレートのタイプ (クラス) に似ています。これは、言語の汎用プログラミング側のみを対象としています。
このように、特定の要件に一致するようにテンプレート パラメーターで使用される型をチェックすることのみを目的としているため、インターフェイス クラスを置き換えることを意図したものではありません (抽象クラス、または C# または Java インターフェイスの他の C++ 同等の実装を意味すると仮定します)。型チェックは、すべてのテンプレート コード生成と同様にコンパイル時にのみ行われますが、インターフェイス クラスは実行時の実行に影響を与えます。
概念は暗黙のインターフェースです。C# または Java では、クラスはインターフェイスを明示的に実装する必要がありますが、C++ では、クラスは、概念の制約を満たしている限り、単に概念の一部です。
Java や C# ではなく C++ で概念が表示される理由は、C++ には実際には「インターフェイス」がないためです。代わりに、複数の継承と抽象的でメンバーのない基本クラスを使用して、インターフェイスをシミュレートできます。これらはハックのようなものであり、扱うのが頭の痛い問題になる可能性があります (例: 仮想継承とダイヤモンド問題)。インターフェイスは OOP とポリモーフィズムで重要な役割を果たしますが、これまで C++ ではその役割が十分に果たされていませんでした。コンセプトは、この問題に対する答えです。
それは多かれ少なかれ視点の違いです。インターフェイス (C# の場合) は基底クラスと同様に指定されますが、概念は自動的に一致することもあります (Python のダックタイピングと同様)。C++ が自動コンセプト マッチングをどのレベルまでサポートするのかはまだ不明です。
私の理解によると、それを簡単に保つために。
概念は、型 (つまり、クラスまたは構造体) またはメソッドのテンプレート パラメーターに対する制約です。
インターフェイスは、タイプ (つまり、クラスまたは構造体) が実装する必要があるコントラクトです。