In java, we can define different interfaces and then later we can implement multiple interface for a concrete class.
// Simulate Java Interface in C++
/*
interface IOne {
void MethodOne(int i);
.... more functions
}
interface ITwo {
double MethodTwo();
... more functions
}
class ABC implements IOne, ITwo {
// implement MethodOne and MethodTwo
}
*/
In C++, generally speaking, we should avoid the usage of multiple inheritance, although multi-inheritance does have its edge on some situations.
class ABC {
public:
virtual void MethodOne(int /*i*/) = 0 {}
virtual double MethodTwo() = 0 {}
virtual ~ABC() = 0 {}
protected:
ABC() {} // ONLY ABC or subclass can access it
};
Question1> Based on the design of ABC
, should I improve any other things in order to make it a decent ABC?
Question2> Is it true that a good ABC
should not contain member variables and instead variables should be kept in the subclasses?
Question3> As I indicated in the comments, what if ABC
has to contain too many pure functions? Is there a better way?
If this is an interface, better do not have any variables there. Otherwise it would be an abstract base class and not an interface.
Too many pure functions is OK unless you can do it with less pure functions.
You've got a couple of syntax errors. For some reason, you're not allowed to put a definition of a pure virtual function inside a class definition; and in any case, you almost certainly don't want to define them in the ABC. So the declarations would usually be:
There's not really any point in making the destructor pure, although it should be virtual (or, in some cases, non-virtual and protected - but it's safest to make it virtual).
There's no need for the protected constructor - the fact that it is abstract already prevents instantiation except as a base class.
Usually, yes. That gives a clean separation between interface and implementation.
The interface should be as complex as it needs to be, and no more. There are only "too many" functions if some are unnecessary; in which case, get rid of them. If the interface looks too complicated, it may be trying to do more than one thing; in that case, you should be able to break it up into smaller interfaces, each with a single purpose.
Like any other language feature, you should use multiple inheritance wherever it is appropriate. Interfaces are generally considered an appropriate use of multiple inheritance (see, for example, COM).
The constructor of
ABC
needs not be protected--it cannot be constructed directly because it is abstract.The
ABC
destructor should not be declared as pure virtual (it should be declared as virtual, of course). You should not require derived classes to implement a user-declared constructor if they do not need one.An interface should not have any state, and thus should not have any member variables, because an interface only defines how something is to be used, not how it is to be implemented.
ABC
should never have too many member functions; it should have exactly the number that are required. If there are too many, you should obviously remove the ones that are not used or not needed, or refactor the interface into several more specific interfaces.First: why should we avoid multiple inheritance in C++? I've never seen a largish application which didn't use it extensively. Inheriting from multiple interfaces is a good example of where it is used.
Note that Java's
interface
is broken—as soon as you want to use programming by contract, you're stuck with using abstract classes, and they don't allow multiple inheritance. In C++, however, it's easy:Alternatively, you could have a compound interface:
and inherit from it, which ever makes the most sense.
This is the more or less standard idiom; in cases where there cannot conceivably be any pre- or post-conditions in the interface (typically call inversion), the virtual functions may be public, but in general, they will be private, so that you can enforce the pre- and post-conditions.
Finally, note that in a lot of cases (especially if the class represents a value), you will just implement it directly, without the interface. Unlike Java, you don't need a separate interface to maintain the implementation in a different file from the class definition—that's the way C++ works by default (with the class definition in a header, but the implementation code in a source file).