C++中的抽象类与接口

fat*_*ici 92 c++ abstract-class interface

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

这是关于C++的一般问题.如你所知,目前还没有明确的区分之间interface以及abstract class在C++与Java和C#.什么时候更喜欢用C++ interface代替abstract class?你能举一些例子吗?

Mr.*_*C64 133

我假设使用接口你的意思是一个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
};
Run Code Online (Sandbox Code Playgroud)

在Windows编程中,接口COM的基础.实际上,COM组件只导出接口(即指向v表的指针,即指向函数指针集的指针).这有助于定义一个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
};
Run Code Online (Sandbox Code Playgroud)

  • @AdrianMaire我的回答是*技术*; 我不为所有人做"广告"_. (8认同)

iam*_*ind 32

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

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

因为第3点interface概念从未在C++中正式引入.仍然可以灵活地做到这一点.

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

  • @Samaursa,这是一个如何**定义**[纯虚方法体]的例子(http://ideone.com/p8zYdG). (4认同)
  • 所以基本上,在c ++中,没有一种语言元素可以强制你在java和c#中使用"类似界面"的行为.但由于"接口"主要是一个概念,您可以使用您提到的语言的功能创建接口. (3认同)

Wil*_*ill 15

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

  • "接口只是一个没有实现方法的抽象类" - 而且没有非静态数据成员,你可以期待. (2认同)

use*_*176 5

纯虚函数主要用于定义:

a) 抽象类

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

b) 接口

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

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