Ответ 1
Я предполагаю, что с интерфейсом вы имеете в виду класс С++ с только чистыми виртуальными методами (т.е. без какого-либо кода), вместо этого с абстрактным классом вы имеете в виду класс С++ с виртуальным методы, которые можно переопределить, и некоторый код, но по крайней мере один чистый виртуальный метод, который делает класс несовместимым. например:.
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-таблицы, т.е. Указатели на набор указателей функций). Это помогает определить ABI (Application Binary Interface), который дает возможность, например, построить COM-компонент на С++ и использовать его в Visual Basic или создать COM-компонент на C и использовать его на С++ или создать COM-компонент с Visual С++ версии X и использовать его с версией Visual С++ Y. Другими словами, с интерфейсами вы имеете высокую развязку между кодом клиента и кодом сервера.
Кроме того, если вы хотите создать DLL с объектно-ориентированным интерфейсом С++ (вместо чистого C DLL), как описано в этой статье, лучше экспортировать интерфейсы ( "зрелый подход" ) вместо классов С++ (это в основном то, что делает 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
};