C ++中的抽象类与接口

时间:2012-10-12 08:07:33

标签: c++ interface abstract-class

  

可能重复:
  How do you declare an interface in C++?

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

5 个答案:

答案 0 :(得分:131)

我认为使用接口表示只有纯虚拟方法的C ++类(即没有任何代码),而是抽象类你的意思是一个C ++类,其中包含可以被覆盖的虚方法,以及一些代码,但至少一个纯虚方法使得该类不可实例化。 e.g:

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-tables 的指针,即指向函数指针集的指针)。这有助于定义 ABI (应用程序二进制接口),使其成为可能。使用C ++构建COM组件并在Visual Basic中使用它,或者在C中构建COM组件并在C ++中使用它,或者使用Visual C ++版本X构建COM组件并将其与Visual C ++版本Y一起使用。 换句话说,使用接口,您可以在客户端代码和服务器代码之间实现高度解耦。

此外,当您想使用C ++面向对象的接口(而不是纯C DLL)构建DLL时,如this article中所述,最好导出 interfaces (“成熟的方法“)而不是C ++类(这基本上是COM所做的,但没有COM基础设施的负担)。

如果我想定义一组可以编程组件的规则,我会使用接口,而不指定具体的特定行为。实现此接口的类本身将提供一些具体的行为。

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

// 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
};

答案 1 :(得分:31)

interface主要受到Java的欢迎 以下是interface及其C ++等价物的性质:

  1. interface只能包含无体抽象方法; C ++等价物是纯virtual方法,尽管它们可以/不能有身体
  2. interface只能包含static final个数据成员; C ++ 等价的是static const数据成员 编译时间常数
  3. 多个interface可由implement class编辑 因为Java class只能继承1,所以需要设施 class;在virtual的帮助下,C ++立即支持多重继承 需要时的关键字
  4. 由于第3点interface概念从未在C ++中正式引入。仍然可以灵活地做到这一点。

    除此之外,你可以在这个主题上引用Bjarne的FAQ

答案 2 :(得分:15)

当需要一些常见的实现时,将使用抽象类。如果您只想指定程序的某些部分也必须符合的合同,那么接口就是如此。通过实现接口,您可以保证实现某些方法。通过扩展抽象类,您将继承其中的一些实现。因此,接口只是一个没有实现方法的抽象类(都是纯虚拟的)。

答案 3 :(得分:2)

纯虚函数主要用于定义:

a)抽象类

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

b)接口

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

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

答案 4 :(得分:0)

请不要将成员放入界面;虽然它在措辞方面是正确的。请不要“删除”界面。

class IInterface() 
{ 
   Public: 
   Virtual ~IInterface(){}; 
   … 
} 

Class ClassImpl : public IInterface 
{ 
    … 
} 

Int main() 
{ 

  IInterface* pInterface = new ClassImpl(); 
  … 
  delete pInterface; // Wrong in OO Programming, correct in C++.
}