1

I have some questions about interfaces in C++.

As far as I understand them, they are used if you want to use a base-class with certain tasks that you already have in mind and you declare some methods for that (but without definition). But every derived class needs to implement these methods for their specific purpose so you create them as abstract methods. And the only difference between abstract classes and interfaces is, that abstract classes have atleast one pure virtual method but also some "normal" methods and interfaces have only pure virtual methods. Is that right?

My professor described interfaces as a way of two classes to communicate with each other. E.g. one interface for a network class and one for an analyzer class who analyzes information from that network. But why do I need an interface for that? Couldn't I just use a normal class for that instead a class which is derived from an interface? He made it sound that in order to extract information from another class you need to have a interface-derived class. Is there any benefit from using an interface here?

I hope my question is clear, English is not my first language.

EDIT: Abstract class: (1/3 methods are pure virtual)

class MyAbstractClass {
public:
  virtual ~MyAbstractClass() {}

  virtual void Method1();
  virtual void Method2();

  virtual void Method3() = 0;
};

Interface: (all methods are pure virtual)

class MyInterface {
public:
  virtual ~MyInterface() {}

  virtual void Method1() = 0;
  virtual void Method2() = 0;
};
  • 2
    A well defined interface is generally nice to have so you can change implementation details transparently. Though you do not need to use abstract classes or even inheritance. For example, standard containers have a uniform interface without inheritance simply by providing similar member functions, making them mostly interchangeable. – François Andrieux Jan 25 '18 at 15:10
  • It's hard to discuss this kind of question without actual code. – llllllllll Jan 25 '18 at 15:10
  • 8
    Beware that "interface" is a word with a metric terrabuttload of meanings in the programming world. Double-check that you are using the same one. – Quentin Jan 25 '18 at 15:11
  • There doesn't exist any language construct named interface in C++. –  Jan 25 '18 at 15:12
  • 1
    @manni66: No, but [there is a way to mimic the concept](https://stackoverflow.com/a/9756896/10077). – Fred Larson Jan 25 '18 at 15:15
  • 2
    @manni66 - Though there is no language construct "named" interface in C++, a pure virtual class is the exact equivalent. – Philippe Lignon Jan 25 '18 at 15:17
  • @manni66 OT, but as I meet you here, this seems to be a rare case of a _**competent** teacher/professor_ ;-) –  Jan 25 '18 at 15:22
  • 4
    Don't confuse the Java term "interface" with the English word "interface". – molbdnilo Jan 25 '18 at 15:24
  • @TheDude yes, you are right. –  Jan 25 '18 at 15:27
  • 2
    Another language comment: don't confuse *being* an interface (or an "abstract class") with *having* or *exposing* an interface. – molbdnilo Jan 25 '18 at 15:34
  • 1
    This is a surprisingly complicated question because C++ also has templates, which can do the same thing as virtual interfaces about 75% of the time, and with marginally better (in rare cases drastically better) performance. What interfaces do is they provide _runtime_ polymorphism. For instance you can fill a single collection with pointers to objects of unrelated classes as long as they're derived from the same interface. – hegel5000 Jan 25 '18 at 15:35
  • 2
    @hegel5000 I'm pretty sure the "marginally better" performance is the rare case though. – Quentin Jan 25 '18 at 15:41

3 Answers3

2

Suppose you were writing the analysis code but a colleague of yours was writing the network code. You could give your collegaue an interface and say 'I don't care what you do as long as you write some code that follows that interface then my code will be able to analyse it'.

But you are right, you don't have to use interfaces, but sometimes they are helpful way of dividing up responsibility.

john
  • 85,011
  • 4
  • 57
  • 81
2

DISCLAIMER: Definitely use virtual interfaces for the course you're taking, if the instructor says so! The below is just an explanation of when you really need to use them.

As it turns out, you can use a regular class using a C++ feature called templates. For instance,

/** ... 
 *  Network must have the following method: 
 *  size_t readsome(char* buffer_out, size_t buffer_size) */
template<typename Network>
class Analyzer {
public:
  Analyzer(/* constructor arguments */);
  void analyze(Network& network) {
    char[50] buffer;
    const size_t read = network.readsome(&buffer, 50);
    /* ... */
  }
  /* I dunno maybe a view_log function should go here. */
private:
  /* ... */
};

Here, Network is a type parameter. You can fill it with any class as long as it has a method called readsome which can fit into the above use case. Note that it's important to document a type parameter's requirements.

Now you can do the following:

CoolNetwork cool_network(/* ... */);
Analyzer<CoolNetwork> analyzer(/* ... */);
while (cool_network.is_open()) { analyzer.analyze(cool_network); }

And separately you can do

CoolerNetwork cooler_network(/* ... */);
Analyzer<CoolerNetwork> analyzer(/* ... */);
while (cooler_network.is_open()) { analyzer.analyze(cooler_network); }

This is static/compile-time/parametric polymorphism (take your pick). But if you want to use a single Analyzer on different types of networks (dynamic/runtime/OO polymorphism), e.g. the following

CoolNetwork cool_network(/* ... */);
CoolerNetwork cooler_network(/* ... */);
Analyzer<Network> analyzer(/* ... */);
while (cool_network.is_open()) { analyzer.analyze(cool_network); }
while (cooler_network.is_open()) { analyzer.analyze(cooler_network); }

Then you need an interface class called Network with a virtual readsome method.

class Network {
public:
  virtual size_t readsome(char* buffer_out, size_t buffer_size) = 0;
  //is_open doesn't have to be in the interface to make the above
  //snippet compile, but it would probably belong here
};

Obviously you should do what's appropriate for the class, but in general (IMO) it's better to default to templates+documentation (simpler, more flexible, more performant), and then up it to interfaces when you need dynamic polymorphism.

hegel5000
  • 876
  • 1
  • 7
  • 13
  • IMO it doesn't matter much, if interfaces are represented as _dynamic_ or _static_ polymorphism. The important point is that the codes works based on certain _contracts_. –  Jan 25 '18 at 18:11
0

But why do I need an interface for that? Couldn't I just use a normal class for that instead a class which is derived from an interface?

Because you usually want to keep the code modifiable for future extensions or adding new analyzers to interact with your network class.
Also there may be different ways to communicate with the underlying network, and you need to keep handling that in a flexible and transparent manner for the analyzer.

He made it sound that in order to extract information from another class you need to have a interface-derived class. Is there any benefit from using an interface here?

It's not strictly necessary, but the benefit is, that if your project manager attends to you to implement something like I stated above (different analysis algorithm or different network transport), it will become way easier to do these changes, without having to rewrite all of the code.

The invariant parts for that can be provided in the abstract base class(es) and extended in the inherited classes for the concrete use cases.

  • Thanks, this really helped. I think I also underestimate the size these interfaces can have. It makes sense to derive just another class from an interface when you have a lot of methods to implement. –  Jan 26 '18 at 10:54
  • @jwBerlin Interfaces usually represent just a small set of functions which are logically related (rule of thumb is 3-5). Implementing classes can inherit multiple interfaces, though another class consuming the interface doesn't need to see all the functions from the implementing class. –  Jan 26 '18 at 11:00