Nov 22, 2009

More Advanced C++ - Polymorphic / Abstract / Virtual example

free web hosting
Open Discussion & Free Web Hosting > Computers & Tech > How-To's and Tutorials > Programming > C and C++

More Advanced C++ - Polymorphic / Abstract / Virtual example

qwijibow
This example assumes you already know basic c++ functions and classes.
it is by no means a complete c++ tutorial, but should give you a good idea of the power of c++.

In this tutorial, i will be using virtualisation, abstraction, and polymorphism to draw a simple picture.
the code is not complete, because i dont want to tie it into any specific operating system.
i will use onlt standard template library finctions, and graphics requires the use of OS specific API's/

We are going to write a program, which holds an array or different shapes.
and (if complete) would draw thenm ot the screen.. (for this example, the will just output somthing like "I am a circle, radius 12, x=20, y=50"

It doesnt sound impressive, but we will be using a single array to hold different classes without using a container. In other words, its like having an array that holds some integers, some booleans, and some strings. it is normally not allowed.

first, before the code, some simple definitions.

=============================
Virtual functions:
=============================
A virtual function is a function which apears to exist to some parts of the code, but aprears not to exist to other parts of the code.

a Pure virtual function is the same, but has no function body. if a class has at least one pure virtual function, then it is considered abstract. meaning it cannot be used directly, but can be used as a template for other functions.

Take a look at the following example program

CODE
#include<iostream>
using namespace std;

class base_class {
public:
[tab][/tab]void function1() {
 cout << "function1 of base_class" << endl;
[tab][/tab]}

[tab][/tab]virtual void function2() {
 cout << "function2 of base_class" << endl;
[tab][/tab]}
};

class sub_class : public base_class {
public:
[tab][/tab]void function2() {
 cout << "function2 of sub_class" << endl;
[tab][/tab]}
};

class sub_class2 : public base_class {};

int main() {

[tab][/tab]base_class BASE;
[tab][/tab]sub_class SUB_A;
[tab][/tab]sub_class2 SUB_B;

[tab][/tab]BASE.function1(); // outputs "function1 of base_class"
[tab][/tab]BASE.function2(); // outputs "function2 of base_class"
[tab][/tab]
[tab][/tab]SUB_A.function1(); // outputs "function1 of base_class"
[tab][/tab]SUB_A.function2(); // outputs "function2 of sub_class"
[tab][/tab]
[tab][/tab]SUB_B.function1(); // outputs "function1 of base_class"
[tab][/tab]SUB_B.function2(); // outputs "function2 of base_class"

[tab][/tab]return 0;
}


virtual function2 in the base class apears to exist, except to the class sub_class, because this class defines its own function2, it over-rides the virtual function.

we could have made function2 a pure virtual function be declairing it like so....
CODE
virtual void function2() = 0;


a pure virtual function exists ONLY to be over-ridden.
you cannot declair an instance of a class containing pure virtual functions, and so if this had been the case, the line

CODE
base_class BASE;
would have caused a compile error.
a class containing pure virtual functions is called abstract.

=============================
Polymorphic objects. (the clever pointer)
=============================

In C++, the pointer rules have been relaxed.
a pointer of type XYZ can point to any class derived from XYZ

the following code example is perfectly legal in c++

CODE
class commom{};

class tree : public common{};
class bird : public common{};
class car : public common{};
class pan_galactic_gargle_blaster : public common{};

int main() {

[tab][/tab]common* array[5];
[tab][/tab]
[tab][/tab]array[0] = new common;
[tab][/tab]array[1] = new tree;
[tab][/tab]array[2] = new bird;
[tab][/tab]array[3] = new car;
[tab][/tab]array[4] = new pan_galactic_gargle_blaster;

[tab][/tab]return 0;
}


=====================================================
MAIN example, combining the 2 examples above.
======================================================
Armed with the ability to have an array of different types, and the ability to over ride functions,
we can do some very clever things.

we are going to write a simpe drawing program.
it will be an array of different shapes, the base class will have a draw() function
which draws different shapes, depending on how it is used. (polymorphic, to change shape! lol )

// include the usual stuff.
CODE
#include<iostream>
#include<vector>

using std::vector;
using std::cout;
using std::cin;


now we need our common base class
CODE
class shape {

protected:
[tab][/tab]int x_position;
[tab][/tab]int y_position;
[tab][/tab]int width;
[tab][/tab]int height;

public:
[tab][/tab]virtual void draw() = 0;

[tab][/tab]void setX(int x) {
 x_position = x;
[tab][/tab]}

[tab][/tab]void setY(int y) {
 y_position = y;
[tab][/tab]}

[tab][/tab]void setW(int w) {
 width = w;
[tab][/tab]}

[tab][/tab]void setH(int h) {
 height = h;
[tab][/tab]}
};


This is ab abstract class because it contains a pure virtual function draw.
the size variables, and manipulation functions are common to all shapes, so they go in the base class.

now lets add some shapes/
CODE
class triangle : public shape {

public:
[tab][/tab]void draw() {
[tab][/tab]
 cout << "i am a triangle" << endl;
 cout << "[tab][/tab]height:" << height << endl;
 cout << "[tab][/tab]width:" << width << endl;
 cout << "[tab][/tab]X:" << x_position << endl;
 cout << "[tab][/tab]Y:" << y_position << endl;
[tab][/tab]}
};

class circle : public shape {

public:
[tab][/tab]void draw() {
[tab][/tab]
 cout << "i am a circle" << endl;
 cout << "[tab][/tab]radius:" << height << endl;
 cout << "[tab][/tab]X:" << x_position << endl;
 cout << "[tab][/tab]Y:" << y_position << endl;
[tab][/tab]}
};

class rectangle : public shape {

public:
[tab][/tab]void draw() {
[tab][/tab]
 cout << "i am a rectangle" << endl;
 cout << "[tab][/tab]height:" << height << endl;
 cout << "[tab][/tab]width:" << width << endl;
 cout << "[tab][/tab]X:" << x_position << endl;
 cout << "[tab][/tab]Y:" << y_position << endl;
[tab][/tab]}
};

class dot : public shape {

public:
[tab][/tab]void draw() {
[tab][/tab]
 cout << "i am a dot" << endl;
 cout << "[tab][/tab]X:" << x_position << endl;
 cout << "[tab][/tab]Y:" << y_position << endl;
[tab][/tab]}
};


each class needs to override the pure virtual function in the shape class.
if a class failed to override the draw() function, then that class would in turn become abstract.

finally, let se out super cool porgram in action.

CODE
int main() {

[tab][/tab]vector<shape*> shapes;

[tab][/tab]shapes.push_back( new triangle() );
[tab][/tab]shapes.push_back( new circle() );
[tab][/tab]shapes.push_back( new rectangle() );
[tab][/tab]shapes.push_back( new dot() );
[tab][/tab]shapes.push_back( new triangle() );
[tab][/tab]shapes.push_back( new circle() );
[tab][/tab]shapes.push_back( new rectangle() );
[tab][/tab]shapes.push_back( new dot() );

[tab][/tab]// set all the shapes member variables (idealy, use random)
[tab][/tab]for(int n=0; n< shapes.size(); n++) {
 shapes[n]->setX(1);
 shapes[n]->setY(2);
 shapes[n]->setH(3);
 shapes[n]->setW(4);
[tab][/tab]}

[tab][/tab]// draw the picture !
[tab][/tab]for(int n=0; n< shapes.size(); n++) {
 shapes[n]->draw();
[tab][/tab]}
[tab][/tab]
      // clean up, prevent memory leaks.
[tab][/tab]for(int n=0; n< shapes.size(); n++) {
 delete shapes[n];
[tab][/tab]}

[tab][/tab]return 0;
}


the vector MUST be a vector of pointers to shapes, and not a vector of shapes.
the the intelligent pointer that knows what functions to call.

and just for fun, the output of the compiled program.
QUOTE
bash-2.05b$ g++ TEST.cpp -o TEST
bash-2.05b$ ./TEST
i am a triangle
        height:3
        width:4
        X:1
        Y:2
i am a circle
        radius:3
        X:1
        Y:2
i am a rectangle
        height:3
        width:4
        X:1
        Y:2
i am a dot
        X:1
        Y:2
i am a triangle
        height:3
        width:4
        X:1
        Y:2
i am a circle
        radius:3
        X:1
        Y:2
i am a rectangle
        height:3
        width:4
        X:1
        Y:2
i am a dot
        X:1
        Y:2


Even advanced C++ isnt too complicated when you understand whats happening.

Any questions / comments / surgestions ?

 

 

 


Comment/Reply (w/o sign-up)

CarolinaBlues
Can you make it easier to understand, You explained it kind of confusingly

Notice from moonwitch:
don't quote an unneeded long quote.

Comment/Reply (w/o sign-up)

warbird
Wow, great tutorial. I couldn't find any good tutorials yet, so I stopped trying to find good C++ resources on the net and focust on books and things. I must say I realy like this one. Could you also write us a tutorial about game programming in C++? Then I realy would be delighted tongue.gif.

-=jeroen=-

Comment/Reply (w/o sign-up)

qwijibow
QUOTE
Could you also write us a tutorial about game programming in C++


I can do the next best thing...
Post a link to a great game programming tutorial.

(well, not really a game programming tutorial, its an OpenGL tutorial, that uses games as its example programs. but still very good)

http://nehe.gamedev.net/


Comment/Reply (w/o sign-up)

MoonLightCity
Great tutorial, thanks for posting this, Ill be sure to test this out when I have time. It looks like a very good tutorial.

Comment/Reply (w/o sign-up)


Got an Opinion! Express your Views! (no registration):-
Add your Reply/ Opinion/ Views/ Comments/ Suggestion/ Questions/ Queries etc.
Posts with decent grammar & English will be accepted and please refrain from profanities.
For asking a Question, We recommend you to sign-up (for free) so that you can track the topic easily.

Nature of your Post*: Opinion/ Reply/ Comments
Question/Query
Feedback to us.
       
Name   Email
Title/Question*

This textarea will convert to Rich-Text automatically (IE, Firefox, Chrome)

Similar Topics

Keywords : Advanced Polymorphic Abstract Virtual


    Looking for advanced, c, polymorphic, abstract, virtual

See Also,

*SIMILAR VIDEOS*
Searching Video's for advanced, c, polymorphic, abstract, virtual
advertisement



More Advanced C++ - Polymorphic / Abstract / Virtual example

Affordable Web Hosting, Low cost Web Hosting - ComputingHost.com