Why can't we create an instance of an abstract class? - c++

I found in many places that :
An Abstract Class is a class which is supposed to be used as a base class.
An Abstract Class is a class which has atleast one Pure Virtual Function.
But one thing that always strikes my mind is why can't we create an instance of an abstract class? Many places on the Internet say there is no point in creating an instance, or some say that they are supposed to be used as base classes. But why is it an error to create an instance of an abstract class?

Your void bar()=0; is not valid -- the =0 notation can only be used with virtual functions.
The whole point of an abstract class is that it's abstract -- you've defined an interface but not an implementation. Without an implementation, instantiating the class wouldn't produce a meaningful or useful result. If it does/would make sense to instantiate objects of that class, then you simply don't want to use an abstract class in the first place.
For example, consider device drivers. We might have a driver for an abstract storage device. We define some capabilities for that device, such as reading and writing data. That abstract class gives any code that wants to read/write data the ability to work with an concrete class that derives from that abstract class.
We can't just instantiate our abstract storage device though. Instead, we need a concrete object like a thumb drive, disk drive, etc., to actually read from/write to. The concrete class is needed because we need code specific to the actual device to carry out the commands we've defined in our abstract base. Our abstract storage class just has a read or write, but do the reading or writing, we need a driver for a specific device. One might know how to talk to a SATA hard drive, while another knows how to talk to a USB thumb drive and a third knows how to read from or write to an SD card. We can't, however, just say "I'm going to create an abstract storage device", and talk to it without defining the actual code that will translate a "write" command into (for example) the right signals going over SATA, USB, Firewire, etc., to get the data onto a real drive.
As such, attempting to instantiate our abstract class makes no sense, and isn't allowed. We just use the abstract base class so the rest of the system can deal with all devices uniformly. The rest of the code doesn't care how the signals are different from each other -- it just sees a bunch of disk drives, and can work with all of them, even though the details of reading data over USB are completely different from reading over Firewire (for example).

An abstract class represents something that isn't specific enough to be instantiated. For instance, what if someone asked you to create a vehicle? You'd have to ask, "what kind of vehicle?" You wouldn't know whether to create a car, a sled, or a space shuttle. There's no such object as a "vehicle". Yet "vehicle" is a useful abstraction that can be used to group objects, indicating common behaviors among them. That's what abstract classes are for.

An abstract class is more than an interface. It may have data members. It may have member functions that are not pure virtual, or non-virtual at all. Even a pure virtual function may have a body, providing a default implementation. So this is not about a physical impossibility of instantiating an abstract class.
The main point is that a pure virtual function is a virtual function that must be overridden by a derived class. That means that a derived class must be defined, and the way to force that is to forbid the instantiation of an abstract class.
An abstract class is not specific enough to be instantiated. Not necessarily because it is missing a definition of a function, because it may not be missing it. It is not specific enough because it represents an abstract concept, which must be made more specific before it can be instantiated.

That's the whole point of an abstract class: that some details must be provided by the implementor.
Think about it: what would be the point of marking a class as abstract if you could instantiate it directly? Then it would be no different than any other class.

The reason an abstract class cannot be instantiated is: what do you do if you execute the pure virtual function? That would be a serious error, and it's better to catch that at compile-time than at runtime.

In abstract class no method definition is given, only structure is provided. If we could instantiate abstract class and call those method, it will be a huge mess. Abstract class is use to maintain a design pattern of the code.

Only Chuck Norris can instantiate an abstract class.
https://api.chucknorris.io/jokes/ye0_hnd3rgq68e_pfvsqqg

Related

Is Abstract class an example of Abstract data type?

I'm getting confused by these two. What I learned is that Abstract data type is a mathematical model for data type, where it specifies the objects and the methods to manipulate these objects without specifying the details about the implementation of the objects and methods. Ex: an abstract stack model defines a stack with push and pop operations to insert and delete items to and from the stack. We can implement this in many ways, by using linked lists, arrays or classes.
Now, coming to the definition of abstract class, its a parent class which has one or more methods that doesn't have definition(implementation?) and cannot be instantiated (much like we can't implement an abstract stack as it is, without defining the stack's underlying mechanism through one of the concrete data structures). For ex: if we have an abstract class called Mammal which includes a function called eat(), we don't know how a mammal eats because a mammal is abstract. Although we can define eat() for a cow which is a derived class of mammal. Does this mean that mammal serves as an adt and cow class is an implementation of the mammal adt?
Correct me if I'm wrong in any way. Any kind of help would be really appreciated.
Abstract data type is a mathematical model for data type...
Now, coming to the definition of abstract class...
You need to distinguish between theoretical mathematical models and a practical implementation techniques.
Models are created by people in order to reason about problems easily, in some comprehensible, generalized way.
Meanwhile, the actual code is written in order to work and get the job done.
"Abstract data type" is a model. "Abstract class" is a programming technique which some programming languages (C++, C#, Java) support on the language level.
"Abstract data type" lets you think and talk about the solution of a problem, without overloading your brain with unnecessary (at this moment) implementation details. When you need a FIFO data structure, you say just "stack", but not "a doubly-linked list with the pointer to the head node and the ability to...".
"Abstract class" lets you write the code once and then reuse it later (because that is the point of OOP - code reuse). When you see that several types have a common interface and functionality - you may create "an abstract class" and put the intersection of their functionality in inside, while still being able to rely on yet unimplemented functions, which will be implemented by some concrete type later. This way, you write the code once and when you need to change it later - it's only one place to make the change in.
Note:
Although, in C++ ISO Standard (at least in the draft) there is a note:
Note: The abstract class mechanism supports the notion of a general concept,
such as a shape, of which only more concrete variants, such as circle
and square, can actually be used.
but it is just a note. The real definition is:
A class is abstract if it has at least one pure (aka unimplemented) virtual function.
which leads to the obvious constraint:
no objects of an abstract class can be created except as subobjects of
a class derived from it
Personally, I like that C++ (unlike C# and Java) doesn't have the keyword "abstract". It only has type inheritance and virtual functions (which may remain unimplemented). This helps you focus on a practical matter: inherit where needed, override where necessary.
In a nutshell, using OOP - be pragmatic.
The term "abstract data type" is not directly related to anything in C++. So abstract class is one of the potential implementation strategies to implement abstract data types in the given language. But there are a lot more techniques to do that.
So abstract base classes allow you to define a set of derived classes and give you the guarantee that all interfaces ( declarations ) have also an implementation, if not, the compiler throws an error, because you can't get an instance of your class because of the missing method definition.
But you also can use compile time polymorphism and related techniques like CRTP to have abstract data types.
So you have to decide which features you need and what price you want to pay for it. Runtime polymorphism comes with the extra cost of vtable and vtable dispatching but with the benefit of late binding. Compile time polymorphism comes with the benefit of much better optimizable code with faster execution and less code size. Both give you errors if an interface is not implemented, at minimum at the linker stage.
But abstract data types with polymorphism, independend of runtime or compile time, is not a 1:1 relation. Making things abstract can also be given by simply defining an interface which must be somewhere fulfilled.
In a short: Abstract data types is not a directly represented in c++ while abstract base class is a c++ technique.
Is Abstract class an example of Abstract data type?
Yes, but in C++, abstract classes have become an increasingly rare example of abstract data types, because generic programming is often a superior alternative.
Ex: an abstract stack model defines a stack with push and pop
operations to insert and delete items to and from the stack. We can
implement this in many ways, by using linked lists, arrays or classes.
The C++ std::stack class template more or less works like this. It has member functions push and pop, and it's implemented in terms of the Container type parameter, which defaults to std::deque.
For an implementation with a linked list, you'd type std::stack<int, std::list<int>>. However, arrays cannot be used to implement a stack, because a stack can grow and shrink, and arrays have a fixed size.
It's very important to understand that the std::stack has absolutely nothing to do with abstract classes or runtime polymorphism. There's not a single virtual function involved.
Now, coming to the definition of abstract class, its a parent class
which has one or more methods that doesn't have
definition(implementation?) and cannot be instantiated
Yes, that's precisely the definition of an abstract class in C++.
In theory, such a stack class could look like this:
template <class T>
class Stack
{
public:
virtual ~Stack() = 0;
virtual void push(T const& value) = 0;
virtual T pop() = 0;
};
In this example, the element type is still generic, but the implementation of the container is meant to be provided by a concrete derived class. Such container designs are idiomatic in other languages, but not in C++.
much like we can't implement an abstract stack as it is, without defining the stack's underlying mechanism through one of the concrete data structures
Yes, you couldn't use std::stack without providing a container type parameter (but that's impossible anyway, because there's the default std::deque parameter), and you cannot instantiate a Stack<int> my_stack; either.

What benefit I will get to create an abstract class rather than the base class in CPP?

In our project - C++, we have the generic module called "ContentCache". From this contentcache, we have derived the customer specific contentcache - for example - Airtel, TataSky. For example, the base contentCache has the method - create the database table, store the basic information. The other types of contentcache which has a relationship like airtel content cache is a type of contentcache. This airtel content cache is customized - overriden a few methods. However, the rest of it are the same. On a few products, we simply use the generic - contentCache. My question is do we need an abstract class - ContentCache - IcontentCache. Also, what is the good way - creating an abstract class or just create a generic base class. What advantage do we get with the IContentCache- i.e. abstract class. I am looking an answer from the design pattern point of view. Also, the programming point of view.
usually you use an abstract class if you define some functionality which can only be used if some additional, unavailable information (or functionality), is needed for that class to work. The unavailable but required information is defined as abstract methods of the class, then derived classes provide that extra information (or functionality).
In your example, if you can usefully have a generic ContentCache then it doesn't need to be abstract. But you might have a design where a ContentCache cannot be instantiated without knowing the name of the specific customer. In this case you might define all of the cache functionality in the abstract base class and have an abstract method which provides the name of the customer. Then in the derived classes you provide the implementation which returns that customer name and the class then has everything it needs to create the cache.
Admittedly this is not a great example as you could just provide the customer name in the constructor of the class, but you mention that in the derived classes you 'override a few methods'. These methods might be candidates for being abstract if they provide functionality which cannot be determined without knowing the customer.
Abstract class is better than just a normal base class. From the design perspective when ever we design a base class , we know that there is going to be inheritance (virtual functions). So we try to collect the common functions in the base class which will mostly be over ride in the derived class. Abstract means hiding the actual implementations from the outside world.Our implementations are our wealth.So base class needs to only work as an interface kind of thing and it should not have any implementation.
Abstract classes are good for you when ever your derived classes are going to ALWAYS use their derived class function definition rathar than using the base class definition.
Normal base classes will be useful , if you are going to use the base class virtual function definition along with the derived class function definition. Normal base class it will be good for small inheritance levels.

Factory Pattern in C++ -- doing this correctly?

I am relatively new to "design patterns" as they are referred to in a formal sense. I've not been a professional for very long, so I'm pretty new to this.
We've got a pure virtual interface base class. This interface class is obviously to provide the definition of what functionality its derived children are supposed to do. The current use and situation in the software dictates what type of derived child we want to use, so I recommended creating a wrapper that will communicate which type of derived child we want and return a Base pointer that points to a new derived object. This wrapper, to my understanding, is a factory.
Well, a colleague of mine created a static function in the Base class to act as the factory. This causes me trouble for two reasons. First, it seems to break the interface nature of the Base class. It feels wrong to me that the interface would itself need to have knowledge of the children derived from it.
Secondly, it causes more problems when I try to re-use the Base class across two different Qt projects. One project is where I am implementing the first (and probably only real implementation for this one class... though i want to use the same method for two other features that will have several different derived classes) derived class and the second is the actual application where my code will eventually be used. My colleague has created a derived class to act as a tester for the real application while I code my part. This means that I've got to add his headers and cpp files to my project, and that just seems wrong since I'm not even using his code for the project while I implement my part (but he will use mine when it is finished).
Am I correct in thinking that the factory really needs to be a wrapper around the Base class rather than the Base acting as the factory?
You do NOT want to use your interface class as the factory class. For one, if it is a true interface class, there is no implementation. Second, if the interface class does have some implementation defined (in addition to the pure virtual functions), making a static factory method now forces the base class to be recompiled every time you add a child class implementation.
The best way to implement the factory pattern is to have your interface class separate from your factory.
A very simple (and incomplete) example is below:
class MyInterface
{
public:
virtual void MyFunc() = 0;
};
class MyImplementation : public MyInterface
{
public:
virtual void MyFunc() {}
};
class MyFactory
{
public:
static MyInterface* CreateImplementation(...);
};
I'd have to agree with you. Probably one of the most important principles of object oriented programming is to have a single responsibility for the scope of a piece of code (whether it's a method, class or namespace). In your case, your base class serves the purpose of defining an interface. Adding a factory method to that class, violates that principle, opening the door to a world of shi... trouble.
Yes, a static factory method in the interface (base class) requires it to have knowledge of all possible instantiations. That way, you don't get any of the flexibility the Factory Method pattern is intended to bring.
The Factory should be an independent piece of code, used by client code to create instances. You have to decide somewhere in your program what concrete instance to create. Factory Method allows you to avoid having the same decision spread out through your client code. If later you want to change the implementation (or e.g. for testing), you have just one place to edit: this may be e.g. a simple global change, through conditional compilation (usually for tests), or even via a dependency injection configuration file.
Be careful about how client code communicates what kind of implementation it wants: that's not an uncommon way of reintroducing the dependencies factories are meant to hide.
It's not uncommon to see factory member functions in a class, but it makes my eyes bleed. Often their use have been mixed up with the functionality of the named constructor idiom. Moving the creation function(s) to a separate factory class will buy you more flexibility also to swap factories during testing.
When the interface is just for hiding the implementation details and there will be only one implementation of the Base interface ever, it could be ok to couple them. In that case, the factory function is just a new name for the constructor of the actual implementation.
However, that case is rare. Except when explicit designed having only one implementation ever, you are better off to assume that multiple implementations will exist at some point in time, if only for testing (as you discovered).
So usually it is better to split the Factory part into a separate class.

What is special about the abstract class mechanism in C++?

I have question that bothers me for few days.
Abstract class is a special type of class that we cannot instantiate, right?. (Which is denoted/specified by giving a "= 0" to at least one method declaration, which looks like an afterthought).
What are the extra benefits that the abstract class mechanism brings to C++, that a 'normal' base class cannot achieve?
According to the wikibooks section on abstract classes:
It's a way of forcing a contract between the class designer and the users of that class. If we wish to create a concrete class (a class that can be instantiated) from an abstract class we must declare and define a matching member function for each abstract member function of the base class.
As mentioned, it's a way of defining an interface to which derived classes must adhere. Their example of the Vehicle abstract class is very apropos: you'd never have just a Vehicle in real life, you'd have a Ford Explorer or a Toyota Prius, but those both conform to (for the sake of argument) a base set of functionality that being a Vehicle might define. But, you can't just go to the Vehicle dealership and drive a Vehicle off the lot. Thus, you'd never want to be able to construct and use a base Vehicle object where you'd really want a specialized, derived object.
This offers the best way in C++ to define an interface without any default implementation.
C++ does not have C#'s interface concept.
It's the equivalent of what Java turned into "interfaces". Basically, it implies that the class itself is not usable - you need to override all pure methods.
An example is MFC's CView class which has a pure OnDraw method - the basic CView doesn't do anything and is as such useless. You have to override OnDraw.
(Btw - it is still possible to provide an implementation for a pure method, and subclassed implementations can fall back to it, but they still have to provide their own override.)
They are used as a base class in a class hierarchy design.
Abstract classes are used to define a clean interface for all derived classes.
At design stage, abstract classes define an interface, per specification and derived classes implement the desired functionality accordingly.
Also using abstract classes instead of "normal" classes helps separating the implementation details from the interface.
A concrete class implements an interface, but the abstract class defines it. You could use a concrete class as a base class in your design but abstract classes are not meant to be used directly in code and can not be instantiated. They serve as prototype.
By using the "normal" class as you say, you have to define an implementation for all methods.
Don't think of it at the class level.
Look at the method, and think of what it should do in the default case:
virtual std::string getName() const = 0;
What would be a right implementation for this method ? There is none than I can think of.
By marking it "pure virtual", you ensure that if the user ever get an instance of a class derived from your interface, then this method will have a sensible behavior.
The only other way to do this would be a throw NotImplemented("getName"); body, but then you'd discover the issue at runtime, not at compile-time, which is not as nice :)

Using non-abstract class as base

I need to finish others developer work but problem is that he started in different way...
So now I found in situation to use existing code where he chooses to inherit a non-abstract class (very big class, without any virtual functions) that already implements bunch of interfaces or to dismiss that code (which shouldn't be to much work) and to write another class that implements interfaces I need.
What are the pros and cons that would help me to choose the better approach.
p.s. please note that I don't have to much experience
Many Thanks
Although it is very tempting to say write it from scratch again, don't do it! The existing code may be ugly, but it looks like it does work. Since the class is big, I assume there is fair bit of history behind it as well. It might have solutions for some very obscure cases which you might not have imagined till now. What I suggest is, if possible first talk to the person who developed that class, understand how it works, then derive from it (after making its destructor virtual of course) and complete your work. Then as and when time permits slowly refactor the parts of the class into smaller more manageable classes. Also, don't forget to write a good unit-tester before you start so that you can validate the new behavior against the existing class's behavior. One more thing, there is nothing wrong in inheriting from a non-abstract base class as long as it makes sense and the base class destructor is virtual.
If the other developer has written a base-class with no virtual functions, then those functions do not need to be overridden, and it is correct to define them in a non-abstract base class.
If those functions define functionality that all the child-classes require then it would be a mistake to get rid of the base class, as you would then need to implement those functions individually in each of the child classes.
I've seen a lot of developers go 'interface-mad' in the last couple of years, but base classes still serve a function over interfaces - to provide a concrete implementation that is common to all child classes. It would be a mistake to get rid of the base class and have seperate implementations of these functions in each of the child classes.
HOWEVER, if the child classes are inheriting functionality that they do not require, or require a separate implementation of, then the Base class is a mistake and interfaces would seem like the better option to divide the functionality between the child classes.
Despite this, I would agree with Naveen that its probably not worth the extra work this will give you, it may seem simple, but if this is a big class with a lot of inheritors then it could turn out to be a nightmare. Quite often in Software Engineering you have to deal with another developer's code that you might have implemented differently. If you re-implemented it ever time you will be a very unproductive developer. I say work with what you've got and get the project finished on time.
Is there anything at all you want to use from the base class or would you end up overriding everything?
Does it define some sort of type that you want to use for an "is-a" relationship?
(for example, base class is "animal" and you want to make "cat", but if it doesn't add any behavior to its interface, that doesn't seem likely)
Is the base class used in other interfaces you need to use? (like if someone is passing objects through a reference/pointer to the base class)
If not, I'd say there's no advantage in inheriting from that class over implementing the interface(s) yourself.
What are the pros and cons that would help me to choose the better approach.
It's legal to derive from a class with no virtual functions, but that doesn't make it a good idea. When you derive from a class with virtual functions, you often use that class through pointers (eg., a class Derived that inherits from Base is often manipulated through Base*s). That doesn't work when you don't use virtual functions. Also, if you have a pointer to the base class, delete-ing it can lead to a memory leak.
However, it sounds more like these classes aren't being used through pointers-to-the-base. Instead the base class is simply used to get a lot of built in functionality, although the classes aren't related in the normal sense. Inversion of control (and has-a relationships) is a more common way to do that nowadays (split the functionality of the base class into a number of interfaces -- pure virtual base classes -- and then have the objects that currently derive from the base class instead have member variables of those interfaces).
At the very least, you'll want to split the big base class into well-defined smaller classes and use those (like mixins), which sounds like your second option.
However, that doesn't mean rewrite all the other code that uses the blob base class all in one go. That's a big undertaking and you're likely to make small typos and similar mistakes. Instead, buy yourself copies of Working Effectively With Legacy Code and Large-Scale C++ Software Design, and do the work piecemeal.
From you question it is not too clear what the problem is - looking at the title (Using non-abstract class as base) I can tell you that using an abstract class (non pure virtual - when you talk about interfaces in C++ I am assuming pure virtual abstract classes) as base makes sense only if there is common functionality you can share between subclasses - meaning that a number of classes extend the same abstract class inheriting the common implementation. If that's not the case (and you're pretty confident it's never gonna happen) then it doesn't make sense to use an abstract class.
If you can extract out some of the functionality in you big class in such a way that leads to (even potential) code reuse then it could make sense - otherwise I wouldn't see the point.