I've just learned about polymorphism in my OOP Class and I'm having a hard time understanding how abstract base classes are useful.
What is the purpose of an abstract class? What does defining an abstract base class provide that isn't provided by creating each necessary function in each actual class?
The purpose of an abstract class is to define a common protocol for a set of concrete subclasses. This is useful when defining objects that share code, abstract ideas, etc.
Abstract classes have no instances. An abstract class must have at least one deferred method (or function). To accomplish this in C++, a pure virtual member function is declared but not defined in the abstract class:
class MyClass {
virtual void pureVirtualFunction() = 0;
}
Attempts to instantiate an abstract class will always result in a compiler error.
"What does defining an abstract base class provide that isn't provided
by creating each necessary function in each actual class?"
The main idea here is code reuse and proper partitioning across classes. It makes more sense to define a function once in a parent class rather than defining over and over again in multiple subclasses:
class A {
void func1();
virtual void func2() = 0;
}
class B : public A {
// inherits A's func1()
virtual void func2(); // Function defined in implementation file
}
class C : public A {
// inherits A's func1()
virtual void func2(); // Function defined in implementation file
}
Having an abstract class like "Dog" with a virtual method like "bark" allows all classes that inherit from Dog to have their bark code called in the same way, even though the Beagle's bark is implemented way differently than the Collie's.
Without a common abstract parent (or at least a common parent with a bark virtual method) it'd be difficult to do the following:
Have a Vector of type Dog that contains Collies, Beagles, German Shepherds etc and make each of them bark. With a Vector of Dogs that contains Collies, Beagles, German Shepherds all you would have to do to make them all bark is to iterate through in a for loop and call bark on each one. Otherwise you'd have to have a separate Vector of Collies, Vector of Beagles etc.
If the question is "why make Dog abstract when it could be concrete, have a virtual bark defined with a default implementation that can be overriden?", the answer would be that this may be acceptable sometimes -- but, from a design perspective, there really isn't any such thing as a Dog that isn't a Collie or a Beagle or some other breed or mix so although they are all Dogs, there is not one of them in reality that is a Dog but not some other derived class too. Also, since dogs barking is so varied from one breed to another, there is unlikely to be any real acceptable default implementation of bark that would be acceptable for any decent group of Dogs.
I hope this helps you understand the purpose: yes, you're going to have to implement bark in each subclass anyway, but the common abstract ancestor lets you treat any subclass as a member of a base class and invoke behaviors that may be conceptually similar like bark but in fact have very different implementations.
Abstract classes allow for compile time protocol enforcement. These protocols define what it means to be a part of a class family.
Another way to think of it is that a abstract class is a contract that your implementing classes must fulfill. If they do not fulfill this contract they cannot be part of the class family and they must be modified to conform to the contract. The provided contract may provide default functionality, but it also leaves it up to the sub-class to define more specific or different functionality while still remaining within the scope of the contract.
For small projects this may not seem useful but for large projects it provides conformity and structure as it provides documentation through the abstract class contract. This makes for more maintainable code and makes for the sub-classes to each have the same protocol making using and developing new sub-classes easier.
The purpose of an abstract class is to provide an appropriate base class from which other classes can inherit. Abstract classes cannot be used to instantiate objects and serves only as an interface. Attempting to instantiate an object of an abstract class causes a compilation error. (because vtable entry is not filled with memory location for virtual function we mentioned in Abstract Class)
Thus, if a subclass of an ABC needs to be instantiated, it has to implement each of the virtual functions, which means that it supports the interface declared by the ABC. Failure to override a pure virtual function in a derived class, then attempting to instantiate objects of that class, is a compilation error.
Example:
class mobileinternet
{
public:
virtual enableinternet()=0;//defines as virtual so that each class can overwrite
};
class 2gplan : public mobileinternet
{
private:
int providelowspeedinternet(); //logic to give less speed.
public:
void enableinternet(int) {
// implement logic
}
};
//similarly
class 3gplan : public enableinternet
{
private: high speed logic (different then both of the above)
public:
/* */
}
here in this example, you can understand.
I have a dog. Abstract class dog with a method bark. My particular dog makes one bark. Other dogs bark in a different way. So defining a dog in the abstract way is useful.
Abstract classes are used to define an interface to be implemented. See some references:
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Abstract_Classes
An abstract class AbstractClass as a base class is needed when there is functionality that is desired for all objects that have a type deriving from AbstractClass, but cannot sensibly be implemented on the AbstractClass itself.
The old and somewhat artificial OO example of having a base class Vehicle with derived classes Car, Motorcycle, ... provides a good example here, say you want a method move() - you can implement the way that a Car or a Motorcycle moves, but Vehicles don't move in a generic way, so Vehicle::move() will have to be pure virtual and Vehicle therefore abstract.
why don't we create each necessary function in each class ? (C++)
You have to create each necessary function marked as abstract in each derived class.
If you question is, why to create abstract function in abstract class?
It allows strict run time polymorphism.
Also read Interface vs Abstract Class (general OO)
abstract class dog
{
bark();
}
// function inside another module
dogbarking(dog obj)
{
dog.bark(); // function will call depend up on address inside the obj
}
// our class
ourclass: inherit dog
{
bark()
{
//body
}
}
main()
{
ourclass obj;
dogbarking(obj);
}
we can see that dogbarking is a function written in another module. it knows only the abstract class dog. even though it can call the function bark inside ourclass. in main function we create object of ourclass and pass to function dogbarking where it received using reference object of abstract class dog.
Imagine you have two methods for displaying a string:
DisplayDialog(string s);
PrintToConsole(string s);
And you want to write some code that can be switched between these two methods:
void foo(bool useDialogs) {
if (useDialogs) {
DisplayDialog("Hello, World!");
} else {
PrintToConsole("Hello, World!");
}
if (useDialogs) {
DisplayDialog("The result of 2 * 3 is ");
} else {
PrintToConsole("The result of 2 * 3 is ");
}
int i = 2 * 3;
string s = to_string(i);
if (useDialogs) {
DisplayDialog(s);
} else {
PrintToConsole(s);
}
}
This code is tightly coupled to the specific methods used for displaying the string. Adding an additional method, changing how the method is selected, etc. will affect every piece of code that uses this. This code is tightly coupled to the set of methods we use to display strings.
Abstract base classes are a way of decoupling code that uses some functionality from the code that implements that functionality. It does this by defining a common interface to all the various ways of doing the task.
class AbstractStringDisplayer {
public:
virtual display(string s) = 0;
virtual ~AbstractStringDisplayer();
};
void foo(AbstractStringDisplayer *asd) {
asd->display("Hello, World!");
asd->display("The result of 2 * 3 is ");
int i = 2 * 3;
string s = to_string(i);
asd->display(s);
}
int main() {
AbstractStringDisplayer *asd = getStringDisplayerBasedOnUserPreferencesOrWhatever();
foo(asd);
}
Using the interface defined by AbstractStringDisplayer we can create and use as many new ways of displaying strings as we want, and code that uses the abstract interface won't need to be changed.
Related
I've a question regarding a concept. First, I'm a mechanical engineer and not a programmer, thus I have some C++ knowledge but not much experience. I use the finite element method (FEM) to solve partial differential equations.
I have a base class Solver and two child linSolver, for linear FEM, and nlinSolver for non-linear FEM. The members and methods that both children share are in the base class. The base class members are all protected. Thus using inheritance makes the child classes "easy to use", like there weren't any inheritance or other boundaries. The base class itself, Solver, is incomplete, meaning only the children are of any use to me.
The concept works actually pretty good - but I think that having an unusable class is a bad design. In addition I read that protected inheritance is not preferred and should be avoided if possible. I think the last point don't really apply to my specific use, since I will never use it allow and any attempt to do so will fail (since it is incomplete).
The questions are:
Is it common to use inheritance to reduce double code even if the base class will be unusable?
What are alternatives or better solutions to such a problem?
Is protected inheritance really bad?
Thank you for your time.
Dnaiel
Having "unusable" base classes is actually very common. You can have the base class to define a common interface usable by the classes that inherits the base-class. And if you declare those interface-functions virtual you can use e.g. references or pointers to the base-class and the correct function in the inherited class object will be called.
Like this:
class Base
{
public:
virtual ~Base() {}
virtual void someFunction() = 0; // Declares an abstract function
};
class ChildA : public Base
{
public:
void someFunction() { /* implementation here */ }
};
class ChildB : public Base
{
public:
void someFunction() { /* other implementation here */ }
};
With the above classes, you can do
Base* ptr1 = new ChildA;
Base* ptr2 = new ChildB;
ptr1->someFunction(); // Calls `ChildA::someFunction`
ptr2->someFunction(); // Calls `ChildB::someFunction`
However this will not work:
Base baseObject; // Compilation error! Base class is "unusable" by itself
While the (working) example above is simple, think about what you could do when passing the pointers to a function. Instead of having two overloaded functions each taking the actual class, you can have a single function which takes a pointer to the base class, and the compiler and runtime-system will make sure that the correct (virtual) functions are called:
void aGlobalFunction(Base* ptr)
{
// Will call either `ChildA::someFunction` or `ChildB::someFunction`
// depending on which pointer is passed as argument
ptr->someFunction();
}
...
aGlobalFunction(ptr1);
aGlobalFunction(ptr2);
Even though the base-class is "unusable" directly, it still provides some functionality that is part of the core of how C++ can be (and is) used.
Of course, the base class doesn't have to be all interface, it can contain other common (protected) helper or utility functions that can be used from all classes that inherits the base class. Remember that inheritance is a "is-a" relationship between classes. If you have two different classes that both "is-a" something, then using inheritance is probably a very good solution.
You should check the concept of Abstract class.
It's designed to provide base class that cannot be instantiated.
To do so you provide at least one method in the base class like this
virtual void f()=0;
Each child have to override the f function (or any pure virtual function from the base class) in order to be instantiable.
Don't think of the BaseClass as a class in its own right, but as an interface contract and some implementation help. Therefore, it should be abstract, if neccessary by declaring the dtor pure virtual but providing an implementation anyway. Some OO purists may frown upon any non-private element, but purity is not a good target.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Can someone explain C++ Virtual Methods?
I have a question regarding to the C++ virtual functions.
Why and when do we use virtual functions? Can anyone give me a real time implementation or use of virtual functions?
You use virtual functions when you want to override a certain behavior (read method) for your derived class rather than the one implemented for the base class and you want to do so at run-time through a pointer to the base class.
The classic example is when you have a base class called Shape and concrete shapes (classes) that derive from it. Each concrete class overrides (implements a virtual method) called Draw().
The class hierarchy is as follows:
The following snippet shows the usage of the example; it creates an array of Shape class pointers wherein each points to a distinct derived class object. At run-time, invoking the Draw() method results in the calling of the method overridden by that derived class and the particular Shape is drawn (or rendered).
Shape *basep[] = { &line_obj, &tri_obj,
&rect_obj, &cir_obj};
for (i = 0; i < NO_PICTURES; i++)
basep[i] -> Draw ();
The above program just uses the pointer to the base class to store addresses of the derived class objects. This provides a loose coupling because the program does not have to change drastically if a new concrete derived class of shape is added anytime. The reason is that there are minimal code segments that actually use (depend) on the concrete Shape type.
The above is a good example of the Open Closed Principle of the famous SOLID design principles.
You use virtual functions when you need handle different objects in the same way. It`s called polymorphism. Let's imagine you have some base class - something like classical Shape:
class Shape
{
public:
virtual void draw() = 0;
virtual ~Shape() {}
};
class Rectange: public Shape
{
public:
void draw() { // draw rectangle here }
};
class Circle: public Shape
{
public:
void draw() { // draw circle here }
};
Now you can have vector of different shapes:
vector<Shape*> shapes;
shapes.push_back(new Rectangle());
shapes.push_back(new Circle());
And you can draw all shapes like this:
for(vector<Shape*>::iterator i = shapes.begin(); i != shapes.end(); i++)
{
(*i)->draw();
}
In this way you are drawing different shapes with one virtual method - draw(). Proper version of method is selected based on run time information about type of object behind pointer.
Notice
When you use virtual functions you can declare them as pure virtual(like in class Shape, just place " = 0" after method proto). In this case you won't be able to create instance of object with pure virtual function and it will be called Abstract class.
Also notice "virtual" before destructor. In case when you are planning work with objects through pointers to their base classes you should declare destructor virtual, so when you call "delete" for base class pointer, all chain of destructors will be called and there won't be memory leaks.
Think of animals class, and derived from it are cat, dog and cow. Animal class has a
virtual void SaySomething()
{
cout << "Something";
}
function.
Animal *a;
a = new Dog();
a->SaySomething();
Instead of printing "Something", dog should say "Bark", cat should say "Meow". In this example you see that a is a Dog, but there are some times that you have an animal pointer and don't know which animal it is. You don't want to know which animal it is, you just want the animal to say something. So you just call virtual function and cats will say "meow" and dogs will say "bark".
Of course, SaySomething function should have been pure virtual to avoid possible errors.
You would use a virtual function to implement "polymorphism", in particular where you have an object, don't know what the actual underlying type is, but know what operation you want to perform on it, and the implementation of this (how it does it) differs dependent on what type you actually have.
Essentially what is commonly called the "Liskov Substitution Principle" named after Barbara Liskov who spoke about this around 1983.
Where you need to use dynamic runtime decisions where, at the point the code invoking the function is called, you do not know what types may pass through it, either now or in the future, this is a good model to use.
It isn't the only way though. There are all sorts of "callbacks" that can take a "blob" of data and you might have tables of callbacks dependent on a header block in the data that comes in, e.g. a message processor. For this there is no need to use a virtual function, in fact what you would probably use is sort-of how a v-table is implemented only with one entry (e.g. a class with just one virtual function).
Last year I saw some source code (C++) where its author declares static function in base class, but leaves its definition to derived class. I remember there was constraint that only one derived class was permitted to define aforementioned static function.
I know that it is impossible to override static methods, but this trick is exactly what I need. I just can't make it work in my code :) Does anyone know about this feature?
Lets look why this would be useful. Suppose we have some base class (Shape), and its derived classes (Circle, Triangle...). Suppose Shape is part of my core architecture, and derived classes are treated as plugins. I don't want to change my core architecture in future. So we have:
class Shape
{
//other stuff here
static Shape* Factory();
}
class Circle:Shape
{
//other stuff here
static Shape* Factory();
}
Shape is sort of abstract class, and it will not implement Factory method. Method is implemented by one (and only one) of the derived classes. In implementation derived class will return new instance of itself, so it is just a factory method. This trick allowed its author to use this static method in client class in following way:
class Client
{
public Shape* shape;
public Client();
//other stuff here
}
In implementation of constructor he had something like:
Client::Client()
:shape(Shape::Factory())
{
}
This way he was able to instantiate "right" shape derivation without changing core classes in engine. When he wanted some other shape to be used in core classes he just had to define static Factory method in that derived class (and to remove the existing one in other derived class).
This way we have some sort of "static polymorphism". I can't find anything about this technique on the web. Does it even have a name? I am especially interested if something like this could be achieved in C# language? :)
Thanks in advance, and sorry for my bad English.
What it sounds like you are trying to do is a bit messy in my opinion. It feels like a combination of a Factory class, a Singleton and then trying to squish them all back into your result class hierarchy.
The simplest (not necessarily the best) solution I can think of is forget about having either Circle::Factory() or Shape::Factory() and just have a free function called get_default_shape().
class Shape
{
};
class Circle: public Shape
{
};
Shape * get_default_shape()
{
return new Circle;
}
Client::Client()
:shape(get_default_shape())
{
}
The nice bit about this is that its only the implementation of get_default_shape that needs to include Circle.h, all the definition needs is a forward declaration of the Shape class.
Hmm. I have not seen exactly what you describe. It could be that the piece of code you refer to defined the base class static function in the cpp file containing your derived class.
// definition of Circle class
.....
Shape* Shape::Factory()
{
return new Circle();
}
This is not useful in this example but it could be a useful trick if you want to hide the implementation of a class and only publish an abstract base class (to reduce compile time dependencies). It won't work if the base and derived classes are not in the same dll/exe.
Similar things can be achieved in C# by using an IOC framework, with generics, or by registring a factory delegate in your base class. I tend to prefer generics and delegates.
Building a GUI system and I have a few classes for different GUI components that derive from a base "GUIcontrol" class. What I want is to have just one function to return any type of component but be able to work with the functions specific to that component type (functions of the derived class). I noticed that the polymorphism approach is going to become a problem I have to declare all the derived functions in the base which is unnecessary for this, since I will never create an object just from the base class.
class GUIcontrol {
protected:
std::string _name;
// these two methods (along with name()) will be used by all types
virtual void position(/*parameters*/)
virtual void useImage(/*parameters*/)
// these should be only in derived types
virtual void setHotSpot(/*parameters*/);
virtual void setScrollButtons(/*parameters*/);
public:
std::string name();
/*etc*/
}
class GUIbutton : public GUIcontrol {
public:
void setHotSpot(/*parameters*/);
}
class GUIscrollBar : public GUIcontrol {
public:
void setScrollButtons(/*parameters*/);
}
GUIcontrol* GUIsystem::getControl(std::string name);
The problem with this is that if I want to add more functions unique to GUIbutton or GUIscrollBar, or any functions to other derived GUI classes, I also have to declare them virtual in the base class so the compiler doesn't complain about something like "setHotSpot" not being a member of the base class it returns.
The base class does have member functions that will apply to all the derived classes, such as telling the object where it should be positioned, what image it needs to use, what it should be called, etc. But I don't want to keep stuffing the base class with other functions that need to stay exclusive to certain derived classes.
As I keep adding more virtual functions I would end up with a huge blob object for the base class. Can I design this in a cleaner way? Note that I am still not sure if I want to use static_cast/dynamic_cast for getControl() to solve this but just want to know if there are any other ways around this to clean it up.
The base class should only contain methods for functionality common to all controls.
If you're going to use functionality that only makes sense for one type of control, you should be checking that the control is of the correct type anyway, and can then cast it to that type.
The base class is exclusively common functionality. If you want your method to behave differently for different controls, use dynamic_cast. If you want it to act the same for all controls, use a virtual method.
This is your problem:
What I want is to have just one
function to return any type of
component but be able to work with the
functions specific to that component
type (functions of the derived class).
What you want is to treat them the same but differently. Huh. I wonder how you're going to make that work. You need to decide if you want to treat them all the same, or if you want to treat them differently.
Type checking and then downcasting isn't the right way to do this. What you should be doing is placing generic methods onto your base class which perform the types of operations you want, and then overriding them in subclasses. For example, if you want the GUIControl to be able to draw itself, then put a doDraw() method on the base class, then override that in each subclass to do as is needed. If you instead put a getTitleBar(), getText() etc. methods on your subclass, then have the caller downcast and calls those specific methods depending on the type, your encapsulation is broken. If you have some common code that multiple subclasses need to do their drawing, then you factor this out either through another parent class, or through composition. Using dynamic_cast, or putting specific methods on the generic subclass, will likely make your code worse.
If I have this right: You want to be able to pass around base class objects but have a clean way to call specific derived class methods where the derived class implements those methods?
Sounds like the 'mixin' pattern might help:
struct Base
{
virtual ~Base() {}
};
struct Mixin
{
virtual ~Mixin() {}
virtual void mixedMethod() = 0;
};
struct Concrete : Base, Mixin
{
virtual void mixedMethod() { std::cout << "Mixing" << std:: endl; }
};
Base* create() { return new Concrete;}
bool mixIt(Base& b)
{
Mixin* m = dynamic_cast<Mixin*>(&b);
if (m)
m->mixedMethod();
return m;
}
void test ()
{
Base* b = create();
assert(mixIt(*b));
Base base;
assert(!mixIt(base));
}
[ Yes, real code never uses struct for polymorhic classes; just keeping it compact.]
The idea here is that the availability of a given method is encapsulated in the Mixin class, which is an pure abstract base class, possibly with only a single pure virtual function.
If you want "know" your base class object is of the derived type, you can call the mixin classes method. You can wrap the test and the call in a non-member function; this allows you to keep the base calss interface itself clean.
Why would I want to define a C++ interface that contains private methods?
Even in the case where the methods in the public scope will technically suppose to act like template methods that use the private methods upon the interface implementation, even so, we're telling the technical specs. right from the interface.
Isn't this a deviation from the original usage of an interface, ie a public contract between the outside and the interior?
You could also define a friend class, which will make use of some private methods from our class, and so force implementation through the interface. This could be an argument.
What other arguments are for defining a private methods within an interface in C++?
The common OO view is that an interface establishes a single contract that defines how objects that conform to that interface are used and how they behave. The NVI idiom or pattern, I never know when one becomes the other, proposes a change in that mentality by dividing the interface into two separate contracts:
how the interface is to be used
what deriving classes must offer
This is in some sense particular to C++ (in fact to any language with multiple inheritance), where the interface can in fact contain code that adapts from the outer interface --how users see me-- and the inner interface --how I am implemented.
This can be useful in different cases, first when the behavior is common but can be parametrized in only specific ways, with a common algorithm skeleton. Then the algorithm can be implemented in the base class and the extension points in derived elements. In languages without multiple inheritance this has to be implemented by splitting into a class that implements the algorithm based in some parameters that comply with a different 'private' interface. I am using here 'private' in the sense that only your class will use that interface.
The second common usage is that by using the NVI idiom, it is simple to instrument the code by only modifying at the base level:
class Base {
public:
void foo() {
foo_impl();
}
private:
virtual void foo_impl() = 0;
};
The extra cost of having to write the dispatcher foo() { foo_impl(); } is rather small and it allows you to later add a locking mechanism if you convert the code into a multithreaded application, add logging to each call, or a timer to verify how much different implementations take in each function... Since the actual method that is implemented in derived classes is private at this level, you are guaranteed that all polymorphic calls can be instrumented at a single point: the base (this does not block extending classes from making foo_impl public thought)
void Base::foo() {
scoped_log log( "calling foo" ); // we can add traces
lock l(mutex); // thread safety
foo_impl();
}
If the virtual methods were public, then you could not intercept all calls to the methods and would have to add that logging and thread safety to all the derived classes that implement the interface.
You can declare a private virtual method whose purpose is to be derivated. Example :
class CharacterDrawer {
public:
virtual ~CharacterDrawer() = 0;
// draws the character after calling getPosition(), getAnimation(), etc.
void draw(GraphicsContext&);
// other methods
void setLightPosition(const Vector&);
enum Animation {
...
};
private:
virtual Vector getPosition() = 0;
virtual Quaternion getRotation() = 0;
virtual Animation getAnimation() = 0;
virtual float getAnimationPercent() = 0;
};
This object can provide drawing utility for a character, but has to be derivated by an object which provides movement, animation handling, etc.
The advantage of doing like this instead of provinding "setPosition", "setAnimation", etc. is that you don't have to "push" the value at each frame, instead you "pull" it.
I think this can be considered as an interface since these methods have nothing to do with actual implementation of all the drawing-related stuff.
Why would I want to define a C++
interface that contains private
methods?
The question is a bit ambiguous/contradictory: if you define (purely) an interface, that means you define the public access of anything that connects to it. In that sense, you do not define an interface that contains private methods.
I think your question comes from confusing an abstract base class with an interface (please correct me if I'm wrong).
An abstract base class can be a partial (or even complete) functionality implementation, that has at least an abstract member. In this case, it makes as much sense to have private members as it makes for any other class.
In practice it is rarely needed to have pure virtual base classes with no implementation at all (i.e. base classes that only define a list of pure virtual functions and nothing else). One case where that is required is COM/DCOM/XPCOM programming (and there are others). In most cases though it makes sense to add some private implementation to your abstract base class.
In a template method implementation, it can be used to add a specialization constraint: you can't call the virtual method of the base class from the derived class (otherwise, the method would be declared as protected in the base class):
class Base
{
private:
virtual void V() { /*some logic here, not accessible directly from Derived*/}
};
class Derived: public Base
{
private:
virtual void V()
{
Base::V(); // Not allowed: Base::V is not visible from Derived
}
};