抽象类与C ++中的接口

可能重复:
你如何在C ++中声明一个接口?

这是一个关于C ++的普遍问题。 如您所知,C ++中的interfaceabstract class与Java和C#不同,没有明显的区别。 什么时候使用C ++中的interface而不是abstract class更可取? 你能举一些例子吗?

我认为接口是指只有纯虚方法(即没有任何代码)的C ++类,而抽象类是指具有可覆盖的虚方法和一些代码的C ++类,但至less有一个纯虚方法这使得类不可实例化。 例如:

 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-表的指针,即指向函数指针集的指针)。 这有助于定义一个ABI (应用程序二进制接口),使得例如在C ++中构build一个COM组件,并在Visual Basic中使用它,或者在C中构build一个COM组件并在C ++中使用它,或者使用Visual C ++构build一个COM组件版本X,并在Visual C ++版本Y中使用它。换句话说,使用接口可以在客户端代码和服务器代码之间高度分离。

而且,当你想用本文所描述的C ++面向对象的接口(而不是纯C DLL)构buildDLL时,最好导出接口 (“成熟方法”)而不是C ++类(这基本上就是COM,但没有COM基础设施的负担)。

如果我想定义一组规则来使用组件,那么我将使用一个接口 ,而不需要指定一个具体的特定行为。 实现这个接口的类将自己提供一些具体的行为。

相反,当我想提供一些默认的基础结构代码和行为时,我会使用一个抽象类 ,并使客户端代码可以从这个抽象类派生,用一些自定义代码覆盖纯虚拟方法,然后完成这个行为自定义代码。 以一个OpenGL应用程序的基础结构为例。 您可以定义一个抽象类来初始化OpenGL,设置窗口环境等等,然后您可以从这个类派生出来,并为渲染过程和处理用户input实现自定义代码:

 // 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主要是由Javastream行的。
下面是interface及其C ++等价物的性质:

  1. interface只能包含无身体抽象方法; C ++等价物是纯粹的virtual方法,尽pipe它们可以/不能有身体
  2. interface只能包含static final数据成员; C ++等价物是static const数据成员,它们是编译时间常量
  3. 多个interface可以由一个Java class ,这个工具是必需的,因为一个Java class只能inheritance一个class ; 在需要的时候,C ++可以在virtual关键字的帮助下直接支持多重inheritance

由于第3点interface概念从未在C ++中正式引入。 仍然可以有一个灵活性来做到这一点。

除此之外,你可以参考Bjarne关于这个话题的FAQ 。

当需要一些常见的实现时,将使用抽象类。 如果你只是想指定一个合约,程序的某些部分也必须符合,那么这个接口就是这样的。 通过实现一个接口,你保证你将实现某些方法。 通过扩展一个抽象类,你正在inheritance它的一些实现。 因此,一个接口只是一个没有实现方法的抽象类(都是纯虚拟的)。

纯虚函数主要用于定义:

a)抽象类

这些是基类,你必须从它们派生,然后实现纯虚函数。

b)接口

这些都是“空”类,其中所有函数都是纯虚函数,因此您必须导出并实现所有函数。

纯虚函数实际上是在基类中没有实现的function,必须在派生类中实现。

请不要将成员放入界面; 尽pipe在措辞中是正确的。 请不要“删除”一个界面。

 class IInterface() { Public: Virtual ~IInterface(){}; … } Class ClassImpl : public IInterface { … } Int main() { IInterface* pInterface = new ClassImpl(); … delete pInterface; // Wrong in OO Programming, correct in C++. }