When does it make sense to use an abstract class - c++

I'm transitioning from c to c++ and of course, OOP which is proving more difficult than expected. The difficulty isn't understanding the core mechanics of classes and inheritance, but how to use it. I've read book on design patterns but they only show the techniques and paint a vague picture of why the techniques should be used. I am really struggling to find a use for abstract classes. Take the code below for example.
class baseClass {
public:
virtual void func1() = 0;
virtual void func2() = 0;
};
class inhClass1 : baseClass {
public:
void func1();
void func2();
};
class inhClass2 : baseClass{
public:
void func1();
void func2();
};
int main() {}
I frequently see abstract classes set up like this in design books. I understand that with this configuration the inherited classes have access to the public members of the base class. I understand that virtual functions are placeholders for the inherited classes. The problem is I still don't understand how this is useful. I'm trying to compare it to overloading functions and I'm just not seeing a practical use.
What I would really like is for someone to give the simplest example possible to illustrate why an abstract class is actually useful and the best solution for a situation. Don't get me wrong. I'm not saying there isn't a good answer. I just don't understand how to use them correctly.

Abstract classes and interfaces both allow you to define a method signature that subclasses are expected to implement: name, parameters, exceptions, and return type.
Abstract classes can provide a default implementation if a sensible one exists. This means that subclasses do not have to implement such a method; they can use the default implementation if they choose to.
Interfaces do not have such an option. Classes that implement an interface are required to implement all its methods.
In Java the distinction is clear because the language includes the keyword interface.
C++ interfaces are classes that have all virtual methods plus a pure virtual destructor.
Abstract classes and interfaces are used when you want to decouple interface from implementation. They're useful when you know you'll have several implementations to choose from or when you're writing a framework that lets clients plug in their own implementation. The interface provides a contract that clients are expected to adhere to.

One use of abstract classes is to be able to easily switch between different concrete implementations with minimal changes to your code. You do this by declaring a reference variable to the base class type. The only mention of the derived class is during creation. All other code uses the base class reference.

Abstract classes are used to provide abstract representation of some concept you want to implement hiding the details.
For example let's say I want to implement File system interface :-
At abstract level what I can think of?
class FileSystemInterface
{
virtual void openFile();
virtual void closeFile();
virtual void readFile();
virtual void writeFile();
};
At this point of time I am not thinking of anything specific like how they will be handled in windows or linux rather I am focusing on some abstract idea.

Related

why we need interface or pure virtual function in c++

why we need interface ( pure virtual function or abstract class) in c++?
Instead of having abstract class, Can we have a base class with virtual function defined in it, and override that virtual function in derived class.
what would be the advantage and disadvantage with the above approach ( except we can create the object of the base class)?
Pure virtual functions are for when there's no sensible way to implement the function in the base class. For example:
class Shape {
public:
virtual float area() const = 0;
};
You can write derived classes like Circle and Rectangle that implement area() using the specific formulas for those kinds of shapes. But how would you implement area() in Shape itself, if it weren't pure virtual? How do you compute the area of a shape without even knowing what kind of shape it is?
If your function can be implemented (in a useful way) in the base class, then go ahead and implement it. Not all base classes need to be abstract. But some of them just inherently are abstract, like Shape.
Pure virtual functions is your way of telling the users of your class that they cannot use the class on its own, without inheriting from it.
Obviously, you can do what you describe, and the system is going to compile and work as expected. However, an pure virtual function is not a construct for the compiler; it is for humans who read your code. It is with this construct that you tell the readers of your code that they must inherit from your class, because the class is not designed to be instantiated on its own.
You use pure virtual functions in situations when there is no reasonable default implementation for a function. This tells people who implement your class that they must provide certain functionality, and the compiler helps them in detecting situations when they forgot to provide an implementation.
If, on the other hand, you provide a default implementation for a virtual function that should be implemented by a subclass, and then the users of your class library forget to provide an implementation, the problem would not be detected until run-time.
An interface give you the ability to specify a set of behaviors that
all classes that implement the interface will share in common.
Consequently, we can define variables and collections (such as arrays)
that don't have to know in advance what kind of specific object they
will hold, only that they'll hold objects that implement the
interface.
Here
As others have said, an interface is a contractual obligation to implement certain methods, properties and events [...] That's a sufficiently awesome benefit to justify the feature.
and here
(please refer to these very good explanations)

Is it a good convention to virtually inherit from pure virtual (interface) classes?

I often use pure virtual classes (interfaces) to reduce dependencies between implementations of different classes in my current project. It is not unusual for me to even have hierarchies in which I have pure virtual and non-pure virtual classes that extend other pure virtual classes. Here is an example of such a situation:
class Engine
{ /* Declares pure virtual methods only */ }
class RunnableEngine : public virtual Engine
{ /* Defines some of the methods declared in Engine */ }
class RenderingEngine : public virtual Engine
{ /* Declares additional pure virtual methods only */ }
class SimpleOpenGLRenderingEngine : public RunnableEngine,
public virtual RenderingEngine
{ /* Defines the methods declared in Engine and RenderingEngine (that are not
already taken care of by RunnableEngine) */ }
Both RunnableEngine and RenderingEngine extend Engine virtually so that the diamond problem does not affect SimpleOpenGLRenderingEngine.
I want to take a preventative stance against the diamond problem instead of dealing with it when it becomes a problem, especially since I like to write code that is as easy for someone else to use as possible and I don't want them to have to modify my classes so that they can create particular class heirarchies e.g. if Bob wanted to do this:
class BobsRenderingEngine : public virtual RenderingEngine
{ /* Declares additional pure virtual methods only */ }
class BobsOpenGLRenderingEngine : public SimpleOpenGLRenderingEngine,
public BobsRenderingEngine
{ /* Defines the methods declared in BobsRenderingEngine */ }
This would not be possible if I had not made SimpleOpenGLRenderingEngine extend RenderingEngine virtually. I am aware that the probability of Bob wanting to do this may be very low.
So, I have begun using the convention of always extending pure virtual classes virtually so that multiple inheritance from them does not cause the diamond problem. Maybe this is due to me coming from Java and tending to only use single inheritance with non-pure virtual classes. I'm sure it is probably overkill in some situations but are there any downsides to using this convention? Could this cause any problems with performance/functionality etc.? If not I don't see a reason not to use the convention, even if it may often not be needed in the end.
I would say that, in general, encouraging inheritance is a bad idea (and that's what you are doing by using virtual inheritance). Few things are actually well represented with a tree structure which is implied by inheritance. In addition I find that multiple inheritance tend to break the single responsibility rule. I do not know your exact use case and I agree that at times we have no other choice.
However in C++ we have another way to compose objects, encapsulation. I find that the declaration below is far easier to understand and manipulate:
class SimpleOpenGLRenderingEngine
{
public:
RunnableEngine& RunEngine() { return _runner; }
RenderingEngine& Renderer() { return _renderer; }
operator RunnableEngine&() { return _runner; }
operator RenderingEngine&() { return _renderer; }
private:
RunnableEngine _runner;
RenderingEngine _renderer;
};
It is true that the object will use more memory than with virtual inheritance, but I doubt objects that complex are created in massive numbers.
Now let's say you really want to inherit, for some external constraint. Virtual inheritance is still hard to manipulate: you are probably comfortable with it, but people deriving from your classes may not, and will probably not think too much before deriving. I guess a better choice would be to use private inheritance.
class RunnableEngine : private Engine
{
Engine& GetEngine() { return *this; }
operator Engine&() { return *this; }
};
// Similar implementation for RenderingEngine
class SimpleOpenGLRenderingEngine : public RunnableEngine, public RenderingEngine
{ };
Short answer: Yes. You nailed it.
Long answer:
So, I have begun using the convention of always extending pure virtual classes
Note: the proper term is abstract classes, not "pure virtual classes".
I have begun using the convention of always extending [abstract] classes virtually so that multiple inheritance from them does not cause the diamond problem.
Indeed. This is a sound convention, but not just for abstract classes, for all classes which represents an interface, some of which have virtual functions with default implementations.
(The shortcomings of Java force you to only put pure virtual functions and no data member in "interfaces", C++ is more flexible, for good, as usual.)
Could this cause any problems with performance
Virtual-ness has a cost.
Profile your code.
Could this cause any problems with [] functionality etc.?
Possibly (rarely).
You cannot unvirtualise a base class: if some specific derived class needs to have two distinct base class subobjects, you cannot use inheritance for both branches, you need containment.
Well, it's pretty simple. You violated the the single responsibility principle (SPR) and this is the cause of your problem. Your "Engine" class is a God class. A well-designed hierarchy does not invoke this problem.

Use-cases of pure virtual functions with body?

I recently came to know that in C++ pure virtual functions can optionally have a body.
What are the real-world use cases for such functions?
The classic is a pure virtual destructor:
class abstract {
public:
virtual ~abstract() = 0;
};
abstract::~abstract() {}
You make it pure because there's nothing else to make so, and you want the class to be abstract, but you have to provide an implementation nevertheless, because the derived classes' destructors call yours explicitly. Yeah, I know, a pretty silly textbook example, but as such it's a classic. It must have been in the first edition of The C++ Programming Language.
Anyway, I can't remember ever really needing the ability to implement a pure virtual function. To me it seems the only reason this feature is there is because it would have had to be explicitly disallowed and Stroustrup didn't see a reason for that.
If you ever feel you need this feature, you're probably on the wrong track with your design.
Pure virtual functions with or without a body simply mean that the derived types must provide their own implementation.
Pure virtual function bodies in the base class are useful if your derived classes wants to call your base class implementation.
One reason that an abstract base class (with a pure virtual function) might provide an implementation for a pure virtual function it declares is to let derived classes have an easy 'default' they can choose to use. There isn't a whole lot of advantage to this over a normal virtual function that can be optionally overridden - in fact, the only real difference is that you're forcing the derived class to be explicit about using the 'default' base class implementation:
class foo {
public:
virtual int interface();
};
int foo::interface()
{
printf( "default foo::interface() called\n");
return 0;
};
class pure_foo {
public:
virtual int interface() = 0;
};
int pure_foo::interface()
{
printf( "default pure_foo::interface() called\n");
return 42;
}
//------------------------------------
class foobar : public foo {
// no need to override to get default behavior
};
class foobar2 : public pure_foo {
public:
// need to be explicit about the override, even to get default behavior
virtual int interface();
};
int foobar2::interface()
{
// foobar is lazy; it'll just use pure_foo's default
return pure_foo::interface();
}
I'm not sure there's a whole lot of benefit - maybe in cases where a design started out with an abstract class, then over time found that a lot of the derived concrete classes were implementing the same behavior, so they decided to move that behavior into a base class implementation for the pure virtual function.
I suppose it might also be reasonable to put common behavior into the pure virtual function's base class implementation that the derived classes might be expected to modify/enhance/augment.
One use case is calling the pure virtual function from the constructor or the destructor of the class.
The almighty Herb Sutter, former chair of the C++ standard committee, did give 3 scenarios where you might consider providing implementations for pure virtual methods.
Gotta say that personally – I find none of them convincing, and generally consider this to be one of C++'s semantic warts. It seems C++ goes out of its way to build and tear apart abstract-parent vtables, then briefly exposes them only during child construction/destruction, and then the community experts unanimously recommend never to use them.
The only difference of virtual function with body and pure virtual function with body is that existence of second prevent instantiation. You can't mark class abstract in c++.
This question can really be confusing when learning OOD and C++. Personally, one thing constantly coming in my head was something like:
If I needed a Pure Virtual function to also have an implementation, so why make it "Pure" in first place ? Why not just leaving it only "Virtual" and have derivatives, both benefit and override the base implementation ?
The confusion comes to the fact that many developers consider the no body/implementation as the primary goal/benefit of defining a pure virtual function. This is not true!
The absence of body is in most cases a logical consequence of having a pure virtual function. The main benefit of having a pure virtual function is defining a contract: By defining a pure virtual function, you want to force every derivative to always provide their own implementation of the function. This "contract aspect" is very important especially if you are developing something like a public API. Making the function only virtual is not so sufficient because derivatives are no longer forced to provide their own implementation, therefore you may loose the contract aspect (which can be limiting in the case of a public API).
As commonly said :
"Virtual functions can be overrided, Pure Virtual functions must be overrided."
And in most cases, contracts are abstract concepts so it doesn't make sense for the corresponding pure virtual functions to have any implementation.
But sometimes, and because life is weird, you may want to establish a strong contract among derivatives and also want them to somehow benefit from some default implementation while specifying their own behavior for the contract. Even if most book authors recommend to avoid getting yourself into these situations, the language needed to provide a safety net to prevent the worst! A simple virtual function wouldn't be enough since there might be risk of escaping the contract. So the solution C++ provided was to allow pure virtual functions to also be able to provide a default implementation.
The Sutter article cited above gives interesting use cases of having Pure Virtual functions with body.

questions about an article introducing C++ interface

I have been reading an article about C++ interfaces (http://accu.org/index.php/journals/233) and I am completely lost at the part where it says all the virtual member functions should be made private (the section titled "Strengthening the Separation"). It just does not make sense to me at all.
According to the author, the code is like this:
class shape {
public:
virtual ~shape();
virtual void move_x(distance x) = 0;
virtual void move_y(distance y) = 0;
virtual void rotate(angle rotation) = 0;
//...
};
class line : public shape {
public:
line(point end_point_1, point end_point_2);
//...
private:
virtual ~line();
virtual void move_x(distance x);
virtual void move_y(distance y);
virtual void rotate(angle rotation);
//...
};
So we have a pure virtual function which is public, and its implementation (in the line class) which is private.
Could anybody explain how the move_x function can be called? Its access specifier is private, it will lead to an error if I try to do this:
line my_line(point(0,0), point(1,2));
my_line.move_x(-1); // does not compile
Similarly is it correct to say that the drawing interface (see earlier in the article)cannot access these functions either?
Thank you.
The idea is that you'd use those methods via a reference or pointer to shape.
shape &s = my_line;
s.move_x(-1);
This could be justified on the grounds of "reveal only what you need to", or as a form of self-documentation. It proves that the methods are only called in the intended way.
If you have in instance of the line object, you might be tempted to call it's methods. But if the only way you can get at them is by asking for it's shape interface, then the object looks to less like an object and more like a collection of interfaces.
This makes more sense if you imagine line implementing more than one interface.
This advice is applicable to homogeneous hierarchies only -- that is, hierarchies in which derived classes introduce no new functions (except constructors maybe) and just override base class functions. In this case you obviously don't need to work with line instance directly -- only via pointer/reference to shape.
When you have less homogeneous hierarchy, this advice hasn't much sense: how would anyone apply it to cases when derived class introduces new functions, or inherits them from another base class? In this case you sometimes want to work directly with objects of derived class directly, and this advice would lead to inconveniences only.
Further development of this idea -- less radical and usable in more contexts -- Non-Virtual Interface (NVI) by Herb Sutter.
I think that the article highlights the rationale well in this quote:
Now, the only thing users can do with
line is create instances of it. All
usage must be via its interface - i.e.
shape, thus enforcing a stronger
interface/implementation separation.
Before leaving this topic, it is
important to get something straight:
the point of enforcing the
interface/implementation separation is
not to tell users what to do. Rather,
the objective is to underpin the
logical separation - the code now
explains that the key abstraction is
shape, and that line serves to provide
an implementation of shape.
That is, line is not by itself interesting. It's just an implementation of the shape interface, and there may be other implementations. You're particularly interested in the shape interface. Hence, you should only access the implementation through this interface, and not as a standalone class.

Private virtual method in C++

What is the advantage of making a private method virtual in C++?
I have noticed this in an open source C++ project:
class HTMLDocument : public Document, public CachedResourceClient {
private:
virtual bool childAllowed(Node*);
virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
};
Herb Sutter has very nicely explained it here.
Guideline #2: Prefer to make virtual functions private.
This lets the derived classes override the function to customize the
behavior as needed, without further exposing the virtual functions
directly by making them callable by derived classes (as would be
possible if the functions were just protected). The point is that
virtual functions exist to allow customization; unless they also need
to be invoked directly from within derived classes' code, there's no
need to ever make them anything but private
If the method is virtual it can be overridden by derived classes, even if it's private. When the virtual method is called, the overridden version will be invoked.
(Opposed to Herb Sutter quoted by Prasoon Saurav in his answer, the C++ FAQ Lite recommends against private virtuals, mostly because it often confuses people.)
Despite all of the calls to declare a virtual member private, the argument simply doesn't hold water. Frequently, a derived class's override of a virtual function will have to call the base class version. It can't if it's declared private:
class Base
{
private:
int m_data;
virtual void cleanup() { /*do something*/ }
protected:
Base(int idata): m_data (idata) {}
public:
int data() const { return m_data; }
void set_data (int ndata) { m_data = ndata; cleanup(); }
};
class Derived: public Base
{
private:
void cleanup() override
{
// do other stuff
Base::cleanup(); // nope, can't do it
}
public:
Derived (int idata): base(idata) {}
};
You have to declare the base class method protected.
Then, you have to take the ugly expedient of indicating via a comment that the method should be overridden but not called.
class Base
{
...
protected:
// chained virtual function!
// call in your derived version but nowhere else.
// Use set_data instead
virtual void cleanup() { /* do something */ }
...
Thus Herb Sutter's guideline #3...But the horse is out of the barn anyway.
When you declare something protected you're implicitly trusting the writer of any derived class to understand and properly use the protected internals, just the way a friend declaration implies a deeper trust for private members.
Users who get bad behavior from violating that trust (e.g. labeled 'clueless' by not bothering to read your documentation) have only themselves to blame.
Update: I've had some feedback that claims you can "chain" virtual function implementations this way using private virtual functions. If so, I'd sure like to see it.
The C++ compilers I use definitely won't let a derived class implementation call a private base class implementation.
If the C++ committee relaxed "private" to allow this specific access, I'd be all for private virtual functions. As it stands, we're still being advised to lock the barn door after the horse is stolen.
I first came across this concept while reading Scott Meyers' 'Effective C++', Item 35: Consider alternatives to virtual functions. I wanted to reference Scott Mayers for others that may be interested.
It's part of the Template Method Pattern via the Non-Virtual Interface idiom: the public facing methods aren't virtual; rather, they wrap the virtual method calls which are private. The base class can then run logic before and after the private virtual function call:
public:
void NonVirtualCalc(...)
{
// Setup
PrivateVirtualCalcCall(...);
// Clean up
}
I think that this is a very interesting design pattern and I'm sure you can see how the added control is useful.
Why make the virtual function private? The best reason is that we've already provided a public facing method.
Why not simply make it protected so that I can use the method for other interesting things? I suppose it will always depend on your design and how you believe the base class fits in. I would argue that the derived class maker should focus on implementing the required logic; everything else is already taken care of. Also, there's the matter of encapsulation.
From a C++ perspective, it's completely legitimate to override a private virtual method even though you won't be able to call it from your class. This supports the design described above.
I use them to allow derived classes to "fill in the blanks" for a base class without exposing such a hole to end users. For example, I have highly stateful objects deriving from a common base, which can only implement 2/3 of the overall state machine (the derived classes provide the remaining 1/3 depending on a template argument, and the base cannot be a template for other reasons).
I NEED to have the common base class in order to make many of the public APIs work correctly (I'm using variadic templates), but I cannot let that object out into the wild. Worse, if I leave the craters in the state machine- in the form of pure virtual functions- anywhere but in "Private", I allow a clever or clueless user deriving from one of its child classes to override methods that users should never touch. So, I put the state machine 'brains' in PRIVATE virtual functions. Then the immediate children of the base class fill in the blanks on their NON-virtual overrides, and users can safely use the resulting objects or create their own further derived classes without worrying about messing up the state machine.
As for the argument that you shouldn't HAVE public virtual methods, I say BS. Users can improperly override private virtuals just as easily as public ones- they're defining new classes after all. If the public shouldn't modify a given API, don't make it virtual AT ALL in publicly accessible objects.