Re: Polymorphism question
On 29 Mrz., 15:15, GeertVc <geert.vancomperno...@gmail.com> wrote:
#include <iostream>
#include <vector>
#include <functional>
A portable version of your program would require one
further
#include <algorithm>
(where std::for_each is located)
class Shape
{
public:
virtual void draw(){cout << "Drawing a shhape\n"; };
};
class Triangle : public Shape
{
public:
void draw()
{
static int counter = 0;
cout << "Drawing a trngle number " << counter++ << " from " <<
this << endl;
}
};
class Square : public Shape
{
public:
void draw()
{
static int counter = 0;
cout << "Drawing a square number " << counter++ << " from " <<
this << endl;
}
};
int main()
{
vector<Shape*> shapes;
Triangle t1,t2;
Square s1, s2;
shapes.push_back(&t1);
shapes.push_back(&s1);
shapes.push_back(&t2);
shapes.push_back(&s2);
cout << endl;
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
for_each( shapes.begin(), shapes.end(), mem_fun(&Shape::draw));
cout << endl;
cout << endl;
}
[..]
Why? Since there's each time two instances of the same class created
(two of class triangle and two of class square), I was expecting that
each "for_each" loop was going to call the "draw()" function *of every
object*, not *of every class*.
One can clearly see the different objects that are called (shown by
the "this" value of the object), but I can only conclude that for
objects of the same class, the "draw" function called is always the
same.
Otherwise, I can't explain why the following happens:
Drawing a trngle number 0 from 0x9ff0be7f
Drawing a square number 0 from 0x9ff0be77
Drawing a trngle number 1 from 0x9ff0be7b
Drawing a square number 1 from 0x9ff0be73
There's a static variable in the "draw()" function and that variable
should only increase when calling "draw()" from the same class
instance ("this" value). Now, eg. when triangle object 0x9ff0be7f is
processed, "draw()" is called and the static variable "counter" (which
should belong to "draw()" of object 0x9ff0be7f) is increased.
But when the second triangle object is called (0x9ff0be7b), that same
static variable "counter" which was used with object 0x9ff0be7f, is
again increased.
I was expecting a "counter" variable for function "draw()" of object
0x9ff0be7f and another "counter" variable for function "draw()" of
object 0x9ff0be7b.
Can someone explain this to me, pls?
The program output behaves as expected. You are probably
mixing up two different concepts of static:
1) A function local static variable
2) A static data member
(A third usage variant would apply static as linkage specifier,
e.g. when used to annotate a namespace scope variable)
You are using version (1), that means each of the *different*
functions
references a different counter object. Therefore if you invoke
Triangle::draw it will use "Triangle::draw()::counter" (This is an
inoffical symbolic description) and if you call Square::draw(), it
will use "Square::draw()::counter". Btw., the same result would
have occurred in your example, if you would have defined a static
data member in both class Triangle and class Square, like so:
class Triangle : public Shape
{
static int counter; // Declaration
public:
void draw()
{
cout << "Drawing a trngle number " << counter++ << " from "
<<
this << endl;
}
};
int Triangle::counter; // Definition (initialized with 0)
class Square : public Shape
{
static int counter; // Declaration
public:
void draw()
{
cout << "Drawing a square number " << counter++ << " from "
<<
this << endl;
}
};
int Square::counter; // Definition (initialized with 0)
Each counter exists per class and so Triangle::draw will
use Triangle::counter and Square::draw will use Square::counter.
You could have obtained your expected result, if you would have
added a static data member to the base class Shape:
class Shape
{
protected:
static int counter; // Declaration
public:
virtual void draw(){cout << "Drawing a shhape\n"; };
};
int Shape::counter; // Definition (initialized with 0)
class Triangle : public Shape
{
public:
void draw()
{
cout << "Drawing a trngle number " << counter++ << " from "
<<
this << endl;
}
};
class Square : public Shape
{
public:
void draw()
{
cout << "Drawing a square number " << counter++ << " from "
<<
this << endl;
}
};
Now all derived classes use the very same counter (Shape::counter)
in there corresponding draw overrides.
HTH and Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]