这是关于C ++的一般问题。如您所知,与Java和C#不同,C ++中interface
和abstract class
之间没有明显的区别。什么时候更喜欢在C ++中使用interface
而不是abstract class
?你能举一些例子吗?
答案 0 :(得分:131)
我认为使用接口表示只有纯虚拟方法的C ++类(即没有任何代码),而是抽象类你的意思是一个C ++类,其中包含可以被覆盖的虚方法,以及一些代码,但至少一个纯虚方法使得该类不可实例化。 e.g:
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 ++版本X构建COM组件并将其与Visual C ++版本Y一起使用。 换句话说,使用接口,您可以在客户端代码和服务器代码之间实现高度解耦。
此外,当您想使用C ++面向对象的接口(而不是纯C DLL)构建DLL时,如this article中所述,最好导出 interfaces (“成熟的方法“)而不是C ++类(这基本上是COM所做的,但没有COM基础设施的负担)。
如果我想定义一组可以编程组件的规则,我会使用接口,而不指定具体的特定行为。实现此接口的类本身将提供一些具体的行为。
相反,当我想提供一些默认的基础设施代码和行为时,我会使用抽象类,并使客户端代码可以从这个摘要中派生出来class,使用一些自定义代码覆盖纯虚方法,并使用自定义代码完成此行为。 想想一下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
};
答案 1 :(得分:31)
interface
主要受到Java的欢迎
以下是interface
及其C ++等价物的性质:
interface
只能包含无体抽象方法; C ++等价物是纯virtual
方法,尽管它们可以/不能有身体interface
只能包含static final
个数据成员; C ++
等价的是static const
数据成员
编译时间常数interface
可由implement
class
编辑
因为Java class
只能继承1,所以需要设施
class
;在virtual
的帮助下,C ++立即支持多重继承
需要时的关键字由于第3点interface
概念从未在C ++中正式引入。仍然可以灵活地做到这一点。
除此之外,你可以在这个主题上引用Bjarne的FAQ。
答案 2 :(得分:15)
当需要一些常见的实现时,将使用抽象类。如果您只想指定程序的某些部分也必须符合的合同,那么接口就是如此。通过实现接口,您可以保证实现某些方法。通过扩展抽象类,您将继承其中的一些实现。因此,接口只是一个没有实现方法的抽象类(都是纯虚拟的)。
答案 3 :(得分:2)
纯虚函数主要用于定义:
a)抽象类
这些是基类,您必须从它们派生,然后实现纯虚函数。
b)接口
这些是“空”类,其中所有函数都是纯虚函数,因此您必须派生并实现所有函数。
纯虚函数实际上是在基类中没有实现的函数,必须在派生类中实现。
答案 4 :(得分:0)
请不要将成员放入界面;虽然它在措辞方面是正确的。请不要“删除”界面。
class IInterface()
{
Public:
Virtual ~IInterface(){};
…
}
Class ClassImpl : public IInterface
{
…
}
Int main()
{
IInterface* pInterface = new ClassImpl();
…
delete pInterface; // Wrong in OO Programming, correct in C++.
}