110

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

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

4

5 回答 5

151

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

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++ 构建 COM 组件版本 X 并将其与 Visual C++ 版本 Y 一起使用。换句话说,通过接口,您可以在客户端代码和服务器代码之间实现高度解耦。

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

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

相反,当我想提供一些默认的基础设施代码和行为时,我会使用抽象类,并使客户端代码可以从这个抽象类派生,用一些自定义代码覆盖纯虚拟方法,并完成这个行为自定义代码。以 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
};
于 2012-10-12T08:50:09.733 回答
35

interface主要是由 Java 流行起来的。
以下是其性质interface及其 C++ 等价物:

  1. interface只能包含无主体的抽象方法;C++ 等价物是纯virtual方法,尽管它们可以/不能有主体
  2. interface只能包含static final数据成员;C++ 等价物是static const编译时常量的数据成员
  3. 多个interface可以implement由 Java 编辑class,这个工具是必需的,因为 Javaclass只能继承 1 class;C++ 在需要时借助virtual 关键字立即支持多重继承

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

除此之外,您还可以参考 Bjarne关于此主题的常见问题解答。

于 2012-10-12T08:24:42.173 回答
15

当需要一些通用实现时,将使用抽象类。如果您只想指定程序的某些部分也必须遵守的合同,则接口将是。通过实现一个接口,您保证您将实现某些方法。通过扩展一个抽象类,你继承了它的一些实现。因此,接口只是一个没有实现方法的抽象类(都是纯虚拟的)。

于 2012-10-12T08:11:18.803 回答
5

纯虚函数主要用于定义:

a) 抽象类

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

b) 接口

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

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

于 2012-10-12T10:40:31.233 回答
-1

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

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

Class ClassImpl : public IInterface 
{ 
    … 
} 

Int main() 
{ 

  IInterface* pInterface = new ClassImpl(); 
  … 
  delete pInterface; // Wrong in OO Programming, correct in C++.
}
于 2012-10-12T09:26:38.593 回答