概念(即最近从 C++0x 标准中删除的概念)与 Java 等语言中的接口有何不同?
5 回答
概念是针对编译时多态性的,这意味着参数泛型代码。接口用于运行时多态性。
当你实现一个概念时,你必须实现一个接口。不同之处在于您不必明确表示您正在实施一个概念。如果所需的接口匹配,则没有问题。在接口的情况下,即使您实现了所有必需的功能,您也必须兴奋地说您正在实现它!
我将尝试澄清我的答案:)
想象一下,您正在设计一个容器,该容器接受具有size成员函数的任何类型。我们将概念形式化并称之为 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.
}
在这个函数中,你无法知道在运行时会传递什么圆形或方形!
它们是用于类似工作的两个工具,尽管 Interface(或任何你称之为它们的名称)可以在运行时完成与 Concepts 几乎相同的工作,但您会失去编译时检查和优化的所有好处!
概念就像模板的类型(类):它仅用于语言的通用编程方面。
这样,它并不意味着替换接口类(假设您的意思是抽象类或 C# 或 Java 接口的其他 C++ 等效实现),因为它仅意味着检查模板参数中使用的类型以匹配特定要求。类型检查只在编译时完成,就像所有模板代码生成一样,而接口类对运行时执行有影响。
概念是隐式接口。在 C# 或 Java 中,类必须显式地实现接口,而在 C++ 中,只要满足概念的约束,类就是概念的一部分。
您将在 C++ 中而不是在 Java 或 C# 中看到概念的原因是因为 C++ 并没有真正的“接口”。相反,您可以通过使用多重继承和抽象的无成员基类来模拟接口。这些有点像黑客,使用起来可能会让人头疼(例如虚拟继承和钻石问题)。接口在 OOP 和多态性中起着至关重要的作用,而迄今为止,该作用在 C++ 中还没有得到充分发挥。概念是这个问题的答案。
这或多或少的观点不同。虽然接口(如在 C# 中)的指定类似于基类,但概念也可以自动匹配(类似于 Python 中的鸭子类型)。目前还不清楚 C++ 将支持自动概念匹配到哪个级别,这也是他们放弃它的原因之一。
根据我的理解,保持简单。
Concept is a constraint on the template parameter of a Type (i.e., class or struct) or a Method
Interfaces is a contract that Type (i.e., class Or struct) has to implement.