Reputation:
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;
};
Upvotes: 1
Views: 2607
Reputation: 884
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.
Upvotes: 2
Reputation:
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.
Upvotes: 0
Reputation: 88007
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.
Upvotes: 2