Abstract Class vs Interface in C++
Possible Duplicate:
How do you declare an interface in C++?
这是一个关于C++的一般性问题。正如你所知道的,在C++中,EDCOX1和0的EDCX1和1之间没有明显的区别。在C++中,使用EDCOX1 0Ω代替EDCOX1?1是什么时候更可取?你能举几个例子吗?
我假设接口是指一个C++类,它只有纯的虚拟方法(即没有任何代码),而不是抽象类,你指的是一个C++类,它可以被重写的虚拟方法和一些代码,但是至少有一个纯虚拟方法使得类不可实例化。例如。:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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(应用程序二进制接口),使它可以在C++中构建COM组件并在Visual Basic中使用它,或者在C中构建COM组件并在C++中使用它,或者用VisualC++版本X构建COM组件并使用VisualC++版本Y来使用它。换句话说,通过接口,您可以在客户机代码和服务器代码之间实现高度的解耦。
此外,当您想用C++面向对象接口(而不是纯C DLL)构建DLL时,如本文所述,最好是导出接口("成熟的方法")而不是C++类(这基本上是COM所做的,但没有COM基础设施的负担)。
如果我想定义一组规则,使用这些规则可以对组件进行编程,而不指定具体的特定行为,那么我将使用一个接口。实现此接口的类本身将提供一些具体的行为。
相反,当我想提供一些默认的基础结构代码和行为时,我会使用一个抽象类,并使客户机代码可以从此抽象类派生,用一些自定义代码覆盖纯虚拟方法,并用自定义代码完成此行为。以OpenGL应用程序的基础架构为例。您可以定义一个抽象类来初始化OpenGL、设置窗口环境等,然后您可以从此类派生并实现自定义代码,例如渲染过程和处理用户输入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | // 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 }; |
EDCOX1,0,主要是由Java流行的。以下是
由于点3 EDOCX1,0的概念在C++中从未正式引入。不过,这样做还是有灵活性的。
除此之外,您还可以参考bjarne关于此主题的常见问题解答。
当需要一些公共实现时,将使用抽象类。如果您只想指定一个契约,那么接口应该是程序的各个部分也必须遵守的契约。通过实现接口,您可以保证实现某些方法。通过扩展抽象类,您将继承它的一些实现。因此,接口只是一个抽象类,没有实现任何方法(所有方法都是纯虚拟的)。
纯虚拟函数主要用于定义:
a)抽象类
这些是必须从中派生并实现纯虚拟函数的基类。
b)界面
这些是"空"类,其中所有函数都是纯虚拟的,因此您必须派生并实现所有函数。
纯虚函数实际上是在基类中没有实现的函数,必须在派生类中实现。
请不要将成员放入接口;尽管它的措辞是正确的。请不要"删除"接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class IInterface() { Public: Virtual ~IInterface(){}; … } Class ClassImpl : public IInterface { … } Int main() { IInterface* pInterface = new ClassImpl(); … delete pInterface; // Wrong in OO Programming, correct in C++. } |