Abstract Class vs Interface in C++ [duplicate]
Asked Answered
F

5

117

Possible Duplicate:
How do you declare an interface in C++?

This is a general question about C++. As you know, there is no clear distinction between interface and abstract class in C++ unlike Java and C#. When would it be more preferrable to use an interface instead of an abstract class in C++? Could you give some examples?

Fully answered 12/10, 2012 at 8:7 Comment(8)
As there's no clear distinction you need to define what you mean by "interface" in C++. (If there's no clear distinction then preferring one over the other doesn't make any sense.)Havard
As you said, there is no distinction, so the question is meaningless unless you define what you mean by an interface and how it differs from an abstract class.Montiel
@juanchopanza: +1 to your comment. I could hardly have said it better myself.Havard
There are no interfaces in C++ the language, you can only emulate them through abstract classes.Bogy
I removed the "java" tag. In fact, even if you cite Java in the question, this question is actually about C++.Spender
While the question could certainly have been worded better, to do so would require the asker to have already known the answer. It annoys me to see the smart-asses dog piling on SO so often. @Fatma: Before looking for answers to when or how you need to be clear about why. An "interface" embodies the concept of a contract between clients and an implementation. An "abstract class" contains code that you want to share between multiple implementations of an interface. While the interface is implied in an abstract classes methods, sometimes it is useful to specify the contract in isolation.Plumcot
As the top answer has explained, in C++ this can be achieved using a class with only pure virtual methods. This can look a little odd for developers who learned Java or C# before C++. It seems like boilerplate overkill but the language maintainers have decided that any benefit of special-casing "interface" is outweighed by the potential inconsistency and additional language complexity that would result. C++ doesn't really need any extra complexity.Plumcot
It may also help to think of this contract as a "protocol" for communication with the family of implementations. This is the name by which interfaces are known in some other languages such as Objective-C.Plumcot
S
165

I assume that with interface you mean a C++ class with only pure virtual methods (i.e. without any code), instead with abstract class you mean a C++ class with virtual methods that can be overridden, and some code, but at least one pure virtual method that makes the class not instantiable. 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
};

In Windows programming, interfaces are fundamental in COM. In fact, a COM component exports only interfaces (i.e. pointers to v-tables, i.e. pointers to set of function pointers). This helps defining an ABI (Application Binary Interface) that makes it possible to e.g. build a COM component in C++ and use it in Visual Basic, or build a COM component in C and use it in C++, or build a COM component with Visual C++ version X and use it with Visual C++ version Y. In other words, with interfaces you have high decoupling between client code and server code.

Moreover, when you want to build DLL's with a C++ object-oriented interface (instead of pure C DLL's), as described in this article, it's better to export interfaces (the "mature approach") instead of C++ classes (this is basically what COM does, but without the burden of COM infrastructure).

I'd use an interface if I want to define a set of rules using which a component can be programmed, without specifying a concrete particular behavior. Classes that implement this interface will provide some concrete behavior themselves.

Instead, I'd use an abstract class when I want to provide some default infrastructure code and behavior, and make it possible to client code to derive from this abstract class, overriding the pure virtual methods with some custom code, and complete this behavior with custom code. Think for example of an infrastructure for an OpenGL application. You can define an abstract class that initializes OpenGL, sets up the window environment, etc. and then you can derive from this class and implement custom code for e.g. the rendering process and handling user input:

// 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
};
Spender answered 12/10, 2012 at 8:50 Comment(4)
@AdrianMaire My answer is technical; I DON'T do "advertising" for anyone.Spender
The comment // make MyAbstractClass not instantiable confuses me. Isn't it the deceleration of void Method3(); that makes the class abstract since it's not virtual?Duet
Method3 is just a normal method that must be defined somewhere in the code.Paring
@Duet What makes a class abstract is that it has at least one pure virtual method.Puri
D
35

interface were primarily made popular by Java.
Below are the nature of interface and its C++ equivalents:

  1. interface can contain only body-less abstract methods; C++ equivalent is pure virtual methods, though they can/cannot have body
  2. interface can contain only static final data members; C++ equivalent is static const data members which are compile time constants
  3. Multiple interface can be implemented by a Java class, this facility is needed because a Java class can inherit only 1 class; C++ supports multiple inheritance straight away with help of virtual keyword when needed

Because of point 3 interface concept was never formally introduced in C++. Still one can have a flexibility to do that.

Besides this you can refer Bjarne's FAQ on this topic.

Demagnetize answered 12/10, 2012 at 8:24 Comment(6)
So basically, in c++ there is not an element of the language that forces the "interface like" behavior you have in java and c#. But since "interface" is primarily a concept, you can create interfaces using the features of the language you mention.Paragon
"C++ equivalent is pure virtual methods, though they can/cannot have body" - there is no can, pure virtual by definition have no body in the base class and they must have a body in the derived class. Also, you do not require the virtual keyword for multiple inheritance in C++. In fact, good design that uses multiple inheritance avoids the virtual keyword (well, they try to avoid multiple inheritance altogether if they can).Electrothermics
What do you mean by body outside the class? By definition a pure virtual function does NOT have a body and is NOT optional for the derived classes to over-ride unless they are meant to be derived further in which case they are abstract as well: ideone.com/hc1Zq8.Electrothermics
@Samaursa, Here is an example of how to define body of a pure virtual method.Demagnetize
Funny thing: for pure virtual destructors, you're still supposed to have an (empty) body.Colburn
@David, it's because the destructor is always going to be invoked (implicitly placed by complier) if you declare an object or new up a pointer. Hence for pure virtual destructor, one must define a body, Unless there is no object created. In C++03, a class with all static methods was a good use case where one doesn't define body of pure virtual destructor. But that can be achieved in C++11, by using = delete.Demagnetize
O
16

An abstract class would be used when some common implementation was required. An interface would be if you just want to specify a contract that parts of the program have to conform too. By implementing an interface you are guaranteeing that you will implement certain methods. By extending an abstract class you are inheriting some of it's implementation. Therefore an interface is just an abstract class with no methods implemented (all are pure virtual).

Otolaryngology answered 12/10, 2012 at 8:11 Comment(3)
"an interface is just an abstract class with no methods implemented" - and no non-static data members, you'd expect.Fascism
I would hope that the destructor was implemented even if pure virtual.Havard
Yes, I suppose what I mean is "with nothing implemented".Otolaryngology
T
6

Pure Virtual Functions are mostly used to define:

a) abstract classes

These are base classes where you have to derive from them and then implement the pure virtual functions.

b) interfaces

These are 'empty' classes where all functions are pure virtual and hence you have to derive and then implement all of the functions.

Pure virtual functions are actually functions which have no implementation in base class and have to be implemented in derived class.

Thorathoracic answered 12/10, 2012 at 10:40 Comment(0)
T
-1

Please don't put members into an interface; though it's correct in phrasing. Please don't "delete" an 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++.
}
Tori answered 12/10, 2012 at 9:26 Comment(3)
Can you explain why one should not delete the interface? In this example the interface has a virtual destructor. So the destructor of ClassImpl will be called even if we delete this object via IInterface pointer, no?Balcom
With C++11 and onwards there should be no reason to explicitly new/delete anything. You should use std::make_unique or std::make_shared instead. This will prevent memory leaks and other common errors.Pitfall
This is just using dynamic allocation, which is manually managed. ClassImpl imp(); IInterface& ii = imp; will work fine, and auto-manage all resources. The base class is not instantiable, that is the same, but ii above is a base-class reference to a statically allocated derived class. It will destruct as needed when it goes out of scope automatically. Resources are allocated on the stack, not the heap. std::make_unique "wraps" dynamically allocated contact in a smart pointer object that destructs its content when it goes out of scope. It does use the heap.Roldan

© 2022 - 2024 — McMap. All rights reserved.