Pregunta Clase abstracta vs interfaz en C ++ [duplicar]


Posible duplicado:
¿Cómo declaras una interfaz en C ++? 

Esta es una pregunta general sobre C ++. Como saben, no hay una distinción clara entre interface y abstract class en C ++ a diferencia de Java y C #. ¿Cuándo sería más preferible usar un interface en lugar de un abstract class en C ++? ¿Podría dar algunos ejemplos?


74
2017-10-12 08:07


origen


Respuestas:


Supongo que con interfaz te refieres a una clase de C ++ con solo puro virtual métodos (es decir, sin ningún código), en lugar de con clase abstracta te refieres a una clase de C ++ con métodos virtuales que pueden ser anulados, y algunos códigos, pero al menos un método virtual puro eso hace que la clase no sea instanciable. p.ej.:

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

En la programación de Windows, interfaces son fundamentales en COM. De hecho, un componente COM solo exporta interfaces (es decir, punteros a tablas v, es decir, punteros al conjunto de punteros de función). Esto ayuda a definir un ABI (Aplicación de interfaz binaria) que hace posible, p. compilar un componente COM en C ++ y usarlo en Visual Basic, o crear un componente COM en C y usarlo en C ++, o crear un componente COM con la versión X de Visual C ++ y usarlo con la versión Y de Visual C ++. En otras palabras, con las interfaces tiene alto desacoplamiento entre el código del cliente y el código del servidor.

Además, cuando desee construir DLL con una interfaz orientada a objetos C ++ (en lugar de C DLL puros), como se describe en Este artículo, es mejor exportar interfaces (el "enfoque maduro") en lugar de clases C ++ (esto es básicamente lo que hace COM, pero sin la carga de la infraestructura COM).

Yo usaría un interfaz si quiero definir un conjunto de reglas con las cuales se puede programar un componente, sin especificar un comportamiento particular concreto. Las clases que implementan esta interfaz proporcionarán un cierto comportamiento concreto.

En cambio, usaría un clase abstracta cuando quiero proporcionar algunos valores predeterminados código de infraestructura y el comportamiento, y hacen posible que el código del cliente se derive de esta clase abstracta, anulando los métodos virtuales puros con algún código personalizado, y completar este comportamiento con código personalizado. Piense, por ejemplo, en una infraestructura para una aplicación OpenGL. Puede definir una clase abstracta que inicialice OpenGL, configure el entorno de la ventana, etc. y luego puede derivar de esta clase e implementar código personalizado para, p. Ej. el proceso de renderizado y el manejo de la entrada del usuario:

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

117
2017-10-12 08:50



interface se hicieron populares principalmente por Java.
A continuación están la naturaleza de interface y sus equivalentes en C ++:

  1. interface puede contener solo métodos abstractos sin cuerpo; C ++ equivalente es puro virtual métodos, aunque pueden / no pueden tener cuerpo
  2. interface solo puede contener static final miembros de datos; C ++ equivalente es static const los miembros de datos que son compilar constantes de tiempo
  3. Múltiple interface puede ser implemented por un Java class, esta instalación es necesaria porque un Java class puede heredar solo 1 class; C ++ admite herencia múltiple directamente con la ayuda de virtual palabra clave cuando sea necesario

Debido al punto 3 interface concepto nunca fue formalmente introducido en C ++. Todavía uno puede tener flexibilidad para hacer eso.

Además de esto, puedes referirte a Bjarne's Preguntas más frecuentes sobre este tema.


30
2017-10-12 08:24



Se usaría una clase abstracta cuando se requiriera una implementación común. Una interfaz sería si solo quieres especificar un contrato para que partes del programa también se ajusten. Al implementar una interfaz, está garantizando que implementará ciertos métodos. Al extender una clase abstracta, hereda parte de su implementación. Por lo tanto, una interfaz es solo una clase abstracta sin métodos implementados (todos son puros virtuales).


14
2017-10-12 08:11



Las funciones virtuales puras se utilizan principalmente para definir:

a) clases abstractas

Estas son clases base donde debe derivar de ellas y luego implementar las funciones virtuales puras.

b) interfaces

Estas son clases "vacías" en las que todas las funciones son puramente virtuales y, por lo tanto, debe derivar y luego implementar todas las funciones.

Las funciones virtuales puras son en realidad funciones que no tienen implementación en la clase base y deben implementarse en la clase derivada.


2
2017-10-12 10:40



Por favor, no pongas miembros en una interfaz; aunque es correcto en el fraseo. Por favor, no "elimine" una interfaz.

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
2017-10-12 09:26