Classe abstraite vs Interface en C++ [dupliquer]

Double Possible:

Comment déclarer une interface en C++?

C'est une question générale sur C++. Comme vous le savez, il n'y a pas de distinction claire entre interface et abstract class en C++ contrairement à Java et C#. Quand serait-il préférable d'utiliser un interface au lieu de abstract class en C++? Pourriez-vous donner quelques exemples?

78
demandé sur Community 2012-10-12 12:07:33

5 réponses

je suppose qu'avec interface vous voulez dire une Classe C++ avec seulement méthodes purement virtuelles (i.e. sans aucun code), au lieu de classe abstraite vous voulez dire une Classe C++ avec des méthodes virtuelles qui peuvent être dépassées, et certains codes, mais au moins une méthode virtuelle pure qui rend la classe non instantible. par exemple:

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

dans Windows programming, les interfaces sont fondamentales dans COM . En fait , un composant COM exporte uniquement des interfaces (c'est-à-dire des pointeurs vers V-tables , c'est-à-dire des pointeurs vers un ensemble de pointeurs de fonction). Cela aide à définir un ABI (Application binaire Interface) qui permet par exemple de construire un composant COM en C++ et de l'utiliser dans Visual Basic, ou de construire un composant COM en C et de l'utiliser en C++, ou de construire un composant COM avec Visual C++ version X et utilisez-le avec Visual C++ version Y. En d'autres termes, avec les interfaces, vous avez un découplage élevé entre le code client et le code serveur.

de plus, lorsque vous voulez construire des DLL avec une interface orientée objet C++ (au lieu de C DLL pure), comme décrit dans cet article , il est préférable d'exporter interfaces (l '"approche mature") au lieu de classes c++ (c'est essentiellement ce que COM fait, mais sans le fardeau de COM infrastructure.)

j'utiliserais une interface si je veux définir un ensemble de règles à l'aide desquelles un composant peut être programmé, sans spécifier un comportement particulier concret. Les Classes qui implémentent cette interface fourniront elles-mêmes un comportement concret.

à la place, j'utiliserais une classe abstraite quand je veux fournir une certaine valeur par défaut code d'infrastructure et le comportement, et rendre possible au code client de dériver de cette classe abstraite, en supplantant les méthodes virtuelles pures avec du code personnalisé, et complète ce comportement avec du code personnalisé. Pensez par exemple à une infrastructure pour une application OpenGL. Vous pouvez définir une classe abstraite qui initialise OpenGL, met en place l'environnement window, etc. et puis vous pouvez dériver de cette classe et implémenter du code personnalisé pour par exemple le processus de rendu et la gestion des entrées utilisateur:

// 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
};
119
répondu Mr.C64 2012-10-12 08:50:09

interface sont principalement rendus populaires par Java.

Voici la nature de interface et ses équivalents C++:

  1. interface peut contenir seulement des méthodes abstraites sans corps; c++ équivalent est pur virtual méthodes, bien qu'ils puissent / ne puissent pas avoir de corps
  2. interface peut contenir seulement les membres de données static final ; c++ l'équivalent est static const les membres de données qui sont moment de la compilation constantes
  3. Multiple interface peut être implement ed par un Java class , ce facilité est nécessaire parce Qu'un Java class peut hériter seulement 1 class ; C++ prend immédiatement en charge l'héritage multiple avec l'aide de virtual mot-clé au besoin

en raison du point 3 interface concept n'a jamais été formellement introduit en C++. On peut encore avoir une flexibilité pour faire ça.

vous pouvez vous référer à FAQ de Bjarne sur ce sujet.

31
répondu iammilind 2012-10-12 08:24:42

une classe abstraite serait utilisée lorsqu'une mise en œuvre commune est requise. Une interface serait si vous voulez juste pour spécifier un contrat que les parties du programme sont conformes trop. En implémentant une interface, vous garantissez que vous mettrez en œuvre certaines méthodes. En étendant une classe abstraite, vous héritez d'une partie de sa mise en œuvre. Par conséquent, une interface est juste une classe abstraite sans aucune méthode implémentée (toutes sont purement virtuelles).

14
répondu Will 2012-10-12 08:11:18

des Fonctions Virtuelles Pures sont principalement utilisés pour définir:

a) classes abstraites

ce sont des classes de base où vous devez dériver d'eux et ensuite mettre en œuvre les fonctions virtuelles pures.

b) les interfaces

ce sont des classes' vides ' où toutes les fonctions sont purement virtuelles et donc vous devez dériver et ensuite implémenter toutes les fonctions.

les fonctions virtuelles pures sont en fait des fonctions qui n'ont pas d'implémentation dans la classe de base et doivent être implémentées dans la classe dérivée.

2
répondu user1740176 2012-10-12 10:40:31

Merci de ne pas mettre les membres dans l'interface; si c'est correct dans le phrasé. Merci de ne pas "supprimer" une interface.

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

Class ClassImpl : public IInterface 
{ 
    … 
} 

Int main() 
{ 

  IInterface* pInterface = new ClassImpl(); 
  … 
  delete pInterface; // Wrong in OO Programming, correct in C++.
}
0
répondu zhouchen 2014-08-26 20:31:21