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 :)
Related
I feel very uncomfortable with the concept of abstract classes, and I'd be happy if someone could make it a bit clearer. I do understand that it's also a matter of implementation and personal style, but I'd like to have at least some guidelines to think about when trying to solve a problem.
I thought that abstract classes only represent a type of behavior that their derived classes will inherit. since we cannot instantiate an object from an abstract class type, so if they have a c'tor or any data fields, they should be in protected mode. I've encountered a piece of code today, where the abstract class had a public constructor and it made me even more confused. I have few questions about this:
the only unique thing about abstract classes is that they have pure virtual functions? it's the only thing that prevents me from instantiating object from this class
on what occasions do I want to declare protected fields in an abstract class? when is it useful to add protected constructor? when is a public constructor needed?
I see many different uses of abstract classes, but sometimes I think about totally different solution, which most of the times is much more complicated and cumbersome than the one presented.
Thank you for your time and attention everyone.
Use abstract classes when you want to provide a base implementation for something, leave some parts of the implementation up to the child classes, but make it mandatory to implement the bits and pieces that are missing.
the only unique thing about abstract classes is that they have pure virtual functions?
A class is abstract because some parts of it (methods) are abstract too (have no implementation).
However, you can declare a class as abstract even if it has no abstract method. That is you want to prevent people from instantiating it. (you could in that case also declare the constructor protected)
on what occasions do I want to declare protected fields in an abstract class?
On the same occasion you would declare protected fields for any class: some properties which may be used by child classes
when is it useful to add protected constructor?
When you want to prevent instantiation of objects of a class. If the class is abstract, there is no additional benefit as it will not be intantiable anyway.
when is a public constructor needed?
For abstract classes, it is not. But that is valid. That constructor will then be used by child classes to pass parameters from their own constructors. In the case of abstract classes it may be declared protected without any side effect.
Kindly note that I am no C++ expert, but those questions are valid in any OOP language.
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)
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.
How do you handle a "cannot instantiate abstract class" error in C++?
I have looked at some of the similar errors here and none of them seem to be exactly the same or problem that I am having. But, then again, I will admit that there are several to go over. Here is the compile error:
This leads me to this page:
http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(C2259);k(VS.ERRORLIST)&rd=true
Compile Error C2259 is from a C++ program but the page calls the abstract class an "interface":
Whenever you derive from an interface and implement the interface methods in the derived class with access permissions other than public, you may receive C2259. This occurs because the compiler expects the interface methods implemented in the derived class to have public access. When you implement the member functions for an interface with more restrictive access permissions, the compiler does not consider them to be implementations for the interface methods defined in the interface, which in turn makes the derived class an abstract class.
There are two possible workarounds for the problem:
Make the access permissions public for the implemented methods.
Use the scope resolution operator for the interface methods implemented in the derived class to qualify the implemented method name with the name of the interface.
The bad news is that I have already made all of the methods public in the class:
class AmbientOccluder: public Light {
public:
AmbientOccluder(void);
The error means there are some methods of the class that aren't implemented. You cannot instantiate such a class, so there isn't anything you can do, other than implement all of the methods of the class.
On the other hand, a common pattern is to instantiate a concrete class and assign it to a pointer of an abstract base class:
class Abstract { /* stuff */ 4};
class Derived : virtual public Abstract { /* implement Abstract's methods */ };
Abstract* pAbs = new Derived; // OK
Just an aside, to avoid memory management issues with the above line, you could consider using a smart pointer such as std::unique_ptr:
std::unique_ptr<Abstract> pAbs(new Derived);
Visual Studio's Error List pane only shows you the first line of the error. Invoke View>Output and I bet you'll see something like:
c:\path\to\your\code.cpp(42): error C2259: 'AmbientOccluder' : cannot instantiate abstract class
due to following members:
'ULONG MysteryUnimplementedMethod(void)' : is abstract
c:\path\to\some\include.h(8) : see declaration of 'MysteryUnimplementedMethod'
An abstract class cannot be instantiated by definition. In order to use this class, you must create a concrete subclass which implements all virtual functions of the class. In this case, you most likely have not implemented all the virtual functions declared in Light. This means that AmbientOccluder defaults to an abstract class. For us to further help you, you should include the details of the Light class.
Provide implementation for any pure virtual functions that the class has.
Why can't we create Object of Abstract Class ?
When we create a pure virtual function in Abstract class, we reserve a slot for a function in the VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the VTABLE will be incomplete.
As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of object for such class and will display an errror message whenever you try to do so.
Pure Virtual definitions
Pure Virtual functions can be given a small definition in the Abstract class, which you want all the derived classes to have. Still you cannot create object of Abstract class.
Also, the Pure Virtual function must be defined outside the class definition. If you will define it inside the class definition, complier will give an error. Inline pure virtual definition is Illegal.
In my case i declared a function in COM Control .idl file like
[id(1)] HRESULT MyMethod([in]INT param);
but not declared in my interface .h file like this
STDMETHOD(MyMethod)(INT param);
Problem solved by adding above line into my interface .h file
this might help some one .
If anyone is getting this error from a function, try using a reference to the abstract class in the parameters instead.
void something(Abstract bruh){
}
to
void something(Abstract& bruh){
}
Can't construct an abstract class, even from a subclass. Abstract classes are basically templates for other classes to be built on and don't have constructors themselves. It's kind of another way to do an interface that involves inheritance.
There's a lot of stuff online about polymorphism, and it's all dumb. C++ makes it so that you can inherit from multiple classes at the same time, so abstract classes and interfaces are the same there. I think the reason why abstract classes exist is because some languages, like Java, can only inherit/extend from one class only.
Abstract classes are quite literally an abstract concept. They are parents of classes, but only in our minds. They are an answer to a question that doesn't have a right answer. Like, "What is the predecessor to GTA?" and you'd say, "Well, there's Race n' Chase" but that's not even a correct answer because they're the same game, just with the name changed. Abstract classes are the answer to "what's the parent of that class"? Like you could say "Oh, a String is just a character array" and "a character array is just a couple iterators" and "iterators are just pointers". Abstract classes allow us to formalize these stupid answers into inheritance.
I have answered this question here..Covariant virtual functions return type problem
See if it helps for some one.
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.