473,320 Members | 1,881 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Abstract Class & Virtual function - Real Implementation?

Hi all,
Though I know the concepts of both abstract class & virtual
function (like derived class pointer pointing to base class...then
calling the function with the pointer...), what is the real
implementation usage of these concepts? Where these concepts will be
used. Please provide some illustration (real-time), so that it can be
easily comprehended.

Thanks,
wittyGuy

Jul 23 '05 #1
4 4181

"WittyGuy" <wi**********@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
Hi all,
Though I know the concepts of both abstract class & virtual
function (like derived class pointer pointing to base class...then
calling the function with the pointer...), what is the real
implementation usage of these concepts? Where these concepts will be
used. Please provide some illustration (real-time), so that it can be
easily comprehended.

Thanks,
wittyGuy


Take a look around you, find me an object which you couldn't classify. In
reality, the whole world around you is classified in some way. Life and
genes, elements and materials, businesses and products, date and time,
energy and work, etc.

The basic idea is that you can classify (no pun intended), contain, upcast,
or provide easy code-expansion for a new object based on its provided
derivative(s).

Common example
A Shape class can be an abstract class to derive a Triangle class, a
Rectangle class and a Circle class. A pure-virtual getArea() member function
in the abstract Shape class requires you to define the getArea() member
function in each of its derivatives. The Circle and the Rectangle, for
example, don't rely on the same getArea() member function to calculate its
area.

Note that this makes OO sense since:
A Triangle is_a Shape
A Rectangle is_a Shape
A Circle is_a Shape

Containers
The benefit is now you can use a container that holds any Shape (an array of
Shapes, a vector, a list, stack, queue, etc). The container needs not track
which shape element is a circle, a triangle or a rectangle. The Shape
container needs only satisfy that each element is a pointer to an existing
Shape derivative.

Shapes* shapes[4]; // a container of pointers to Shape objects

shapes[0] = new Rectangle(10, 10); // (width, length)
shapes[1] = new Circle(5); // (radius)
shapes[2] = new Triangle(7, 6) // (width, length)
shapes[3] = new Circle(22); // (radius)

The element at shapes[0] knows whether its a Circle, Rectangle or Triangle.
The same goes with every other element. The container doesn't care whether
Array[2] is a Triangle, a Rectangle or a Circle. So when you write:

int n = 0;
while ( n < 4 )
{
Array[n++]->getArea();
}

delete [] shapes;

You are calling the appropriate getArea() behaviour for each Shape-type
element in the container (using a vtable). This would not be possible
without the abstract Shape class (a container of what?). Neither would this
be possible without a pure-virtual getArea() member function in Shape (we
need to guarentee that all Shapes have such a member function available).

This ability to contain any derivative-type can be applied to Animals,
Vehicles, Employees, Airplanes, Planets or any other base class you can
think of. Note that the hierarchy need not be so shallow. A Car is a
derivative of Vehicle, a Sportscar is a derivative of Car, hence a Sportscar
can also be an element in a container of Vehicles.

Whats the benefit? All such Vehicles have an engine, a steering wheel and a
gas tank. There is no need to repeatedly insert an engine in all the derived
classes. A Vehicle base class can be composed of an engine and each derived
class needs only invoke the appropriate engine ctor to equip itself with a
particular engine. The startEngine() member function in Vehicle can now
start the engine in any Vehicle. This can save an enormous amount of code
when you consider the variety of motorized vehicle-types out there.

Should a client programmer choose to employ your classes (expand Shape to
provide a pentagon or octagon - expand Vehicle to provide a FireTruck), his
job has been made much easier for both you, the creator, and the client.
You've used a common abstract base class and pure-virtual member functions
which dictates and guarentees the implementation of the new derived entity
in the program.

A quick scan by the client of your base class permits him or her to draw up
the derived FireTruck. The client can add the water pump, the ladder, valves
and whatever he likes or needs. Yet that FireTruck can still be held in any
Vehicle container (highway, FireHouse, bridge, Ferry, Tunnel, etc) and the
original startEngine() member function still works.

The same principles of simplified code reusability can be applied in
virtually any appropriate classification hierarchy.

Jul 23 '05 #2
Hi codigo,
That is a perfect illustration which cleared most of my
doubt regarding abstract class usage. But one concept which still
remains unclear is why is it needed that virtual function (not pure
virtual), to get the base class member function thru derived class
pointer of the object invoked instead using pointer of the base class
object straight-away for invocation?

thanx,
wittyGuy

Jul 23 '05 #3
WittyGuy wrote:

Hi codigo,
That is a perfect illustration which cleared most of my
doubt regarding abstract class usage. But one concept which still
remains unclear is why is it needed that virtual function (not pure
virtual), to get the base class member function thru derived class
pointer of the object invoked instead using pointer of the base class
object straight-away for invocation?


???
Your english is not very clear. At least I cannot figure out
what you are asking about.
The function *is* invoked through a base class pointer. In
codigo's example (when all the syntactic errors are fixed)
all the pointers are base class type pointers.

Here is the compilable, working example again. Note that in
main() the for loop deals with Shape pointers only. Yet the
correct function is invoked.

#include <iostream>

class Shape
{
public:
virtual ~Shape() {}; // needs to be virtual since we are going
// to destroy in a polymorphic way

virtual double GetArea() { return 0.0; } // Could be a pure function if wanted
// since this function should never be called.
// But just in case :-)

virtual const char* Description() { return "Shape"; }
};

class Rectangle : public Shape
{
public:
Rectangle( double Width, double Height )
: m_Width( Width ), m_Height( Height )
{}

virtual double GetArea() { return m_Width * m_Height; }
virtual const char* Description() { return "Rectangle"; }

protected:
double m_Width;
double m_Height;
};

class Circle : public Shape
{
public:
Circle( double Radius )
: m_Radius( Radius )
{}

virtual double GetArea() { return m_Radius * m_Radius * 3.1415926; }
virtual const char* Description() { return "Circle"; }

protected:
double m_Radius;
};

int main()
{
Shape* Shapes[2];

Shapes[0] = new Rectangle( 3.0, 5.0 );
Shapes[1] = new Circle( 4.0 );

for( int i = 0; i < 2; ++i ) {
std::cout << i << ": I am a "
<< Shapes[i]->Description()
<< " and my area is "
<< Shapes[i]->GetArea()
<< "\n";
}

delete Shapes[0];
delete Shapes[1];
}

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #4

"WittyGuy" <wi**********@gmail.com> wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com...
Hi codigo,
That is a perfect illustration which cleared most of my
doubt regarding abstract class usage. But one concept which still
remains unclear is why is it needed that virtual function (not pure
virtual), to get the base class member function thru derived class
pointer of the object invoked instead using pointer of the base class
object straight-away for invocation?

thanx,
wittyGuy


You could have used a pure virtual instead of a virtual function. In many
cases this makes sense. A pure virtual getArea() member function requires
that any Shape derivative implement getArea(). It also prevents
instantiation of an underived Shape object.

You could also use a virtual getArea() in the Shape class and protect the
ctor as an alternative (to prevent the instantiation of an underived Shape
object).

The difference between using either a pure-virtual or virtual is that with a
pure-virtual member function, you can't directly call the base's
pure-virtual getArea() and the Shape class is abstract without having to
protect its ctor. However, the vtable mechanism doesn't prevent you from
calling Shape::getArea() from a Circle or Triangle. The language has the
flexibility to meet your needs one way or another.

Lets store the area in an abstract Shape class. Lets calculate the area in
the Shape ctor invocations (in the derived initialization lists).

#include <iostream>
using std::cout;

class Shape
{
const double m_area;
public:
Shape(double a) : m_area(a) { }
virtual ~Shape() {};
virtual double getArea() const = 0
{
return m_area;
}
}; // class Shape

class Circle : public Shape
{
double m_radius;
public:
Circle(double r)
: m_radius(r),
Shape(r * r * 3.1416) { }
~Circle() { }
double getArea() const
{
cout << "Circle's area is ";
return Shape::getArea();
}
}; // class Circle

class Rectangle : public Shape
{
double m_width;
double m_height;
public:
Rectangle(double w, double h)
: m_width(w),
m_height(h),
Shape(w * h) { }
~Rectangle() { }
double getArea() const
{
cout << "Rectangle's area is ";
return Shape::getArea();
}
}; // class Rectangle

class Triangle : public Shape
{
double m_width;
double m_height;
public:
Triangle(double w, double h)
: m_width(w),
m_height(h),
Shape((w * h)/2) { }
~Triangle() { }
double getArea() const
{
cout << "Triangle's area is ";
return Shape::getArea();
}
}; // class Triangle

int main()
{
Shape* shapes[3];

shapes[0] = new Circle(2.5);
shapes[1] = new Rectangle(5.0, 2.0);
shapes[2] = new Triangle(5.0, 2.0);

for( int i = 0; i < 3; ++i )
{
cout << "shapes[" << i << "]: ";
cout << shapes[i]->getArea();
cout << std::endl;
}

delete shapes[0];
delete shapes[1];
delete shapes[2];

return 0;
} // main()

******
output:

shapes[0]: Circle's area is 19.635
shapes[1]: Rectangle's area is 10
shapes[2]: Triangle's area is 5


Jul 23 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Medi Montaseri | last post by:
Hi, Given a collection of similar but not exact entities (or products) Toyota, Ford, Buick, etc; I am contemplating using the Abstraction pattern to provide a common interface to these products....
9
by: Anon Email | last post by:
Hi people, I'm learning about header files in C++. The following is code from Bartosz Milewski: // Code const int maxStack = 16; class IStack
8
by: Dev | last post by:
Hello, Why an Abstract Base Class cannot be instantiated ? Does anybody know of the object construction internals ? What is the missing information that prevents the construction ? TIA....
18
by: Bradley | last post by:
I'm trying to determine if there's a general rule for when an Interface should used vs. an Abstract Class. Is there any design advantage to using one or the other? Brad
7
by: tron.thomas | last post by:
Please consider the following code: class Abstract { public: virtual ~Abstract() {} virtual void Method() = 0; }; class Concrete : public virtual Abstract
6
by: Alden Pierre | last post by:
Hello, http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7 As per the link above it's wise to have a virtual deconstructor when creating an abstract class. Here is when I'm...
0
by: mailforpr | last post by:
Hi. Let me introduce an iterator to you, the so-called "Abstract Iterator" I developed the other day. I actually have no idea if there's another "Abstract Iterator" out there, as I have never...
4
by: David Zha0 | last post by:
Hi, "when we call a virtual method, the runtime will check the instance who called the method and then choose the suitable override method, this may causes the performance drop down", is this...
17
by: Jess | last post by:
Hello, If I have a class that has virtual but non-pure declarations, like class A{ virtual void f(); }; Then is A still an abstract class? Do I have to have "virtual void f() = 0;"...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.