概念与接口有何不同?

Posted

技术标签:

【中文标题】概念与接口有何不同?【英文标题】:How do Concepts differ from Interfaces? 【发布时间】:2009-07-25 22:14:44 【问题描述】:

概念(即最近从 C++0x 标准中删除的概念)与 Java 等语言中的接口有何不同?

【问题讨论】:

C++ 没有任何称为接口的东西,而……哦……等等,它们是一样的。但是您必须先说出“接口”的含义,然后才能回答问题。 Java接口?接口的一般 OOP 概念? API 中作为“I”的接口的一般概念? 纯虚类接口不只是名称不同吗? C++ 没有“纯虚拟类”的概念。它确实有纯虚函数的概念。 @onebyone 到时候我会加入并声称自己是真正的 onebyone!老实说,我认为人们在这里使用他们的真实姓名过于偏执 - 这似乎没有对 Skeet 造成任何伤害! @Gman 我的真名实际上是“Clint Throb”,我选择了“Neil Butterworth”作为别名,因为它听起来更性感。 【参考方案1】:

概念是针对编译时多态性的,即参数泛型代码。接口用于运行时多态性。

您必须在实现概念时实现接口。不同之处在于您不必明确表示您正在实施一个概念。如果所需的接口匹配,则没有问题。在接口的情况下,即使您实现了所有所需的功能,您也必须兴奋地说您正在实现它!


我会尽量澄清我的答案:)

假设您正在设计一个容器,该容器接受具有 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 几乎相同的工作,但您会失去编译时检查和优化的所有好处!

【讨论】:

是的,这个答案对我来说似乎很好。 +1 我是反对者。 AraK 已经完全重新编辑了他的答案,但是由于 SO 的变幻莫测,重新编辑没有出现。 抱歉我写的太匆忙了,第一次没写完:( @AraK,我将“兴奋性”更改为“明确”-这是您的意思吗? (以前没有意义) 为什么说接口用于运行时多态?在编译时检查接口约束。您指的是 vtable 查找吗?此外,您的 doSomething 函数并没有真正显示接口和概念的不同之处,而且似乎有点无关紧要。您将如何以不同的方式完成 doSomething 概念?为什么不使用多态性而不是 if-else 链和强制转换?【参考方案2】:

概念是模板的类似类型(类):它仅适用于语言的通用编程方面。

这样,它并不是要替换接口类(假设您是指抽象类或 C# 或 Java 接口的其他 C++ 等效实现),因为它只是为了检查模板参数中使用的类型以匹配特定要求。 类型检查只在编译时完成,就像所有模板代码生成一样,而接口类对运行时执行有影响。

【讨论】:

【参考方案3】:

概念是隐式接口。在 C# 或 Java 中,类必须显式实现接口,而在 C++ 中,只要满足概念的约束,类就是概念的一部分。

您会在 C++ 中看到概念而不是在 Java 或 C# 中的原因是因为 C++ 并没有真正的“接口”。相反,您可以通过使用多重继承和抽象的无成员基类来模拟接口。这些有点像 hack,使用起来可能会让人头疼(例如虚拟继承和The Diamond Problem)。接口在 OOP 和多态性中起着至关重要的作用,而迄今为止,该作用在 C++ 中还没有得到充分发挥。概念是这个问题的答案。

【讨论】:

【参考方案4】:

这或多或少的观点不同。虽然接口(如在 C# 中)的指定类似于基类,但也可以自动匹配概念(类似于 Python 中的鸭子类型)。目前还不清楚 C++ 将支持自动概念匹配到哪个级别,这也是他们放弃它的原因之一。

【讨论】:

【参考方案5】:

根据我的理解,为了简单起见。

概念是对类型(即类或结构)或方法的模板参数的约束

接口是类型(即类或结构)必须实现的契约。

【讨论】:

以上是关于概念与接口有何不同?的主要内容,如果未能解决你的问题,请参考以下文章

indexedDB 在概念上与 HTML5 本地存储有何不同?

TCP 网络模型的“应用层”与“传输层”有何不同?

结构递归与生成递归有何不同?

如果你有一个只有抽象方法的抽象类怎么办?这与界面有何不同?

websocket与标头connection-keep-alive =million的http有何不同

通过 XML 和 Java 代码使用 OnClickListener 接口有何不同? [复制]